You get a bonus - 1 coin for daily activity. Now you have 1 coin

3 Architectural Patterns 3.1 Layering System

Lecture



One of the strange properties of the software industry is that a term may have many conflicting interpretations. So, the term "architecture" is tried to be interpreted by all and sundry, and everyone in their own way. However, there are two common options. The first is associated with the division of the system into the largest components; in the second case, some constructive decisions are meant, which after their adoption are difficult to change. There is also a growing understanding that there is more than one way to describe the architecture and the degree of importance of each of them varies throughout the life cycle of the system. Architecture is a very subjective concept. At best, it displays the overall view of the development team on the results of system design. Typically, this agreement on the identification of the main components of the system and how they interact, as well as the choice of such solutions, which are interpreted as fundamental and not subject to change in the future. If it later turns out that something is easier to change than it seemed at first, this “something” is easily excluded from the “architectural” category.

Architectural patterns address questions about how to decompose a system into layers (layers) and how to ensure proper interaction between layers. Many of the patterns discussed below can definitely be considered “architectural” in the sense that they represent “significant” components of the application and / or “fundamental” aspects of the functioning of these parts. Others are related to implementation issues.

3.1 Stratification System

The concept of layers (layers) - one of the commonly used models used by software developers to separate complex systems into simpler parts. Computer system architectures, for example, distinguish between layers of code in a programming language, operating system functions, device drivers, CPU instruction sets, and chip internal logic. In a network communication environment, the FTP protocol is based on the TCP protocol, which, in turn, operates on top of the IP protocol located above the Ethernet protocol. Describing a system in terms of architectural layers, it is convenient to perceive its subsystems in the form of a "puff pie". The higher layer uses the services provided by the underlying layer, but it is not “aware” of the presence of the neighboring upper layer. Moreover, usually each intermediate layer “hides” the bottom layer from the top: for example, layer 4 uses the services of layer 3, which refers to layer 2, but layer 4 is not aware of the existence of layer 2. (Not every architecture has layers that are so “impenetrable" , but in most cases this is the case). Dismembering the system into layers provides a number of advantages.

  • A separate layer can be perceived as a single, self-contained whole, without worrying about the presence of other layers (for example, to create an FTP service, you need to know TCP, but not the subtleties of Ethernet).
  • You can choose an alternative implementation of the base layers (FTP applications can work without any changes in the Ethernet environment, over the PPP connection or in any other medium of information transfer).
  • Dependence between layers can be minimized. So, when changing the transmission medium (provided that the IP layer functionality is preserved), the FTP service will continue to work as if nothing had happened.
  • Each layer is a good candidate for standardization (for example, TCP and IP - standards defining the features of functioning of the corresponding layers of the network communications system).
  • The created layer can serve as the basis for several different higher layer layers (TCP / IP protocols are used by FTP, telnet, SSH, and HTTP applications). Otherwise, for each high-level protocol, you would have to invent your own low-level protocol.

The stratification scheme has certain disadvantages.

  • Layers can successfully encapsulate a lot, but not all: the modification of one layer is often associated with the need to make cascading changes to the other layers. A classic example from the field of corporate software applications: a field added to a database table is to be reproduced in the graphical interface and must find a corresponding mapping in each intermediate layer.
  • The presence of excess layers often reduces system performance. When moving from layer to layer, modeled entities are usually subjected to transformations from one representation to another. Despite this, the encapsulation of the underlying functions often makes it possible to achieve a very significant advantage. For example, optimization of the transaction layer usually results in improved performance for all overlying layers. However, the most difficult thing when using architectural layers is to define the contents and limits of responsibility of each layer.

3.1.1.1 Development of the Layer Model in Enterprise Software Applications

The concept of a layer acquired obvious significance in the mid-1990s with the advent of client / server systems (client / server). These were systems with two layers: the client was responsible for displaying the user interface and executing the application code, and the server role was usually assigned to the DBMS. Client applications were created using tools such as Visual Basic, PowerBuilder and Delphi, which provided the developer with everything needed, including on-screen components serving the SQL interface: to construct the window it was enough to drag the necessary controls to the workspace data and connect to it using property tables.

If the tasks were reduced to simple operations for displaying information from the database and its minor updating, the client / server systems operated without fail. Problems arose with the complication of the domain logic - business rules, calculation algorithms, test conditions, etc. Previously, all these responsibilities were assigned to the client code and were reflected in the contents of the interface screens. The more complex the logic became, the more clumsy and difficult to read was the code. Reproducing the elements of logic on the screens led to duplication of the code, and then, if necessary, to make the simplest change, one had to “comb” the entire program in search of identical fragments.

One of the alternatives was the description of logic in the text of stored procedures placed in a database. The languages ​​of the stored procedures, however, were characterized by limited structuring capabilities, which again had a negative effect on the quality of the code. In addition, many preferred relational database systems, since the standardized SQL language used in them opened up the possibilities for a painless transition from one DBMS to another. Although only a few of them took advantage of them in practice, the thought of a possible change in the supplier of a DBMS that was not associated with any tangible costs warmed everyone. And the presence of a hard dependency of the languages ​​of stored procedures on specific versions of systems actually destroyed these hopes.

As client / server systems became more popular, the paradigm of object-oriented programming gained momentum, giving the community the answer to the sacramental question of what to do with business logic: switch to a three-layer system architecture in which the presentation layer is assigned to the user interface, the subject domain layer is designed to describe business logic, and the third layer represents the data source. In this case, it would be possible to separate the interface and logic, placing the latter on a separate level, where it can be structured using appropriate objects.

Despite the efforts made, the movement under the banner of object orientation in the direction of the three-tier architecture was still too timid and unsure. Many projects turned out to be too simple, which didn’t make the programmers want to leave the well-established track of client / server systems and tie themselves with new obligations. In addition, client / server application development tools hardly supported a three-tier computation model or did not provide such tools at all.

A radical shift occurred with the advent of the Web. Everyone suddenly wanted to have a client / server system, where a web browser would act as a client. If, however, the entire business logic of the application was concentrated in the fat client code, when going to the Web interface, you had to revise it completely. And in a well-designed three-level system, it was enough just to replace the presentation level without affecting the domain layer. Later, with the advent of Java, everyone saw an object-oriented language that claims to be universally accepted. The emerging web page design tools were less related to SQL and therefore more suitable for the implementation of the third level.

When discussing issues of stratification of software systems, the concepts of a layer (layer) and a level, or tier are often confused. They are often used as synonyms, but in most cases the term level is interpreted to mean physical separation. Therefore, client / server systems are usually described as two-level (in the general case, the “client” is physically separated from the server): the client is the application for the desktop machine, and the server is the process performed by the network server computer. I use the term layer to emphasize that the layers do not necessarily have to be located on different machines. A separate layer of business logic can function both on a personal computer "side by side" with the client layer of the interface, and on the database server. In such situations, we are talking about two nodes on the network, but three layers or levels. If the database is local, all three layers may coexist on the same computer, but even in this case they must retain their sovereignty.

3.1.1.2 Three main layers

We have already spoken to you about the problem of the system at the level (or layers, layers) when we discussed issues related to the project model. Then we introduced 4 layers: views, business objects (or domain), middleware (often called a data source) and system software. Let us consider in more detail the top three levels (the level of system software is so much dependent on the software and hardware platform that its consideration will either be too narrow (if we talk only about one platform) or too narrow for this course (if we try to consider at least a few options). And so, we focus our attention on the architecture with three main layers: presentation (presentation), domain (subject area, business logic) (domain) and data source (data source). The table shows a brief description

Layer

Functions

Representation

Providing services, displaying data, handling user interface events (mouse clicks and keystrokes), handling HTTP requests, supporting command line functions and batch execution API

Domain

Application business logic

Data source

Database access, messaging, transaction management, etc.

The presentation layer covers everything that relates to the user's communication with the system. It can be as simple as a command line or a text menu, but today the user will most likely have to deal with a graphical interface designed in the style of a thick client (Windows, Swing, etc.) or based on HTML. The main functions of the presentation layer include the display of information and the interpretation of user-entered commands with their transformation into the corresponding operations in the context of the domain (business logic) and data source.

The data source is a subset of the functions that provide interaction with third-party systems that perform tasks in the interests of the application. The code in this category is responsible for monitoring transactions, managing other applications, messaging, etc. For most enterprise applications, the bulk of the data source logic is concentrated in the DBMS code.

The domain logic (business logic or domain logic) describes the main functions of the application designed to achieve its goal. Such functions include calculations based on the input and stored data, checking all data elements and processing commands from the presentation layer, as well as transferring information to the data source layer.

Sometimes layers are organized in such a way that the business logic completely hides the data source from the view. More often, however, the view code can access the data source directly. Although this option is less perfect from a theoretical point of view, in practical terms it is often more convenient and expedient: the presentation code can interpret a user command, activate data source functions to retrieve suitable pieces of information from the database, use business logic to analyze this information. and making the necessary calculations and only then display the corresponding picture on the screen.

Often, within the framework of an application, there are several options for implementing each of the three categories of logic. For example, an application focused on the use of both the thick client interface tools and the command line can (and probably should) be equipped with two appropriate versions of the presentation logic. On the other hand, multiple layers of data sources can respond to different databases. Even a layer of business logic can be divided into separate “packages” (for example, in a situation where the calculation algorithms depend on the type of data source).

Although the three main layers — presentation, business logic, and data source — can be found in any enterprise application, the way they are separated depends on the complexity of the application. A simple script for extracting a portion of information from a database and displaying it in the context of a web page can be described in one procedure. But I would still try to isolate three layers in it - even if, as in this case, by distributing the functions of each layer into different subprograms. With the increasing complexity of the application, this would make it possible to spread the code of the layers into separate classes, and later to break the set of classes into packages. The shape of the bundle can be arbitrary, but in any corporate application the layers must be identified.

In addition to the need for division into layers, there is a rule regarding the relationship of the layers: the dependence of business logic and data source on the presentation level is not allowed. In other words, in the text of the application there should not be calls to the presentation functions from the code of business logic or data source. The rule allows you to simplify the ability to adapt the presentation layer or replace it with an alternative option while preserving the basis of the application. The relationship between business logic and the data source, however, is not so straightforward and is largely determined by the choice of typical solutions for the data source architecture.

The most difficult thing in working on business logic is probably the choice of what exactly and how should be attributed to one or another layer. I like one informal test. Imagine that a fundamentally different layer is added to the program, for example a command line interface for a web application. If there is a certain set of functions that will have to be duplicated for the implementation of what was intended, then the domain logic “flows” into the presentation layer. We can formulate the test in another way: whether it is necessary to repeat the logic if it is necessary to replace the relational database with an XML file.

A good example of a situation is the system that I was once told about. Imagine that the application displays a list of highlighted in red product names, sales of which increased by more than 10% compared to the level of last month. Suppose a programmer has placed the appropriate logic directly in the presentation layer, deciding here to compare the sales levels of the current and last month and change the color if the difference exceeds a predetermined threshold.

The problem is that a logic of the domain that is not typical of it is introduced into the layer of representation. In order to properly separate the layers, you need a business logic method that reflects the fact that the sales level of a certain product is exceeded by a specified amount. The method should compare two-month sales levels and return a boolean-type value. In the code of the presentation layer, it is sufficient to call this method and, guided by the result obtained, decide to change the color of the display. In this case, the process is divided into two parts: the identification of a fact that can serve as a basis for a color change, and the change itself.

And the funniest thing is that both conclusions are actually true!

3.1.1.3 Where levels should function

Throughout this and subsequent lectures we are talking about logical layers, i.e. about the dismemberment of the system into separate parts. This separation is useful even when all layers are running on the same machine. However, there are situations where differences in the behavior of the system may be due to the principles of its physical organization.

In most cases, there are only two options for locating and executing components of corporate applications - on a personal computer and on a server.

Often the easiest is to operate the code of all layers of the system on the server. This becomes possible, for example, when using the HTML interface played by a web browser. The main advantage of concentrating all parts of the application in one place is that it simplifies the procedures for correcting errors and updating versions to the maximum. In this case, you do not have to worry about making appropriate changes on all computers, their compatibility with other applications and synchronization with server components.

Общие аргументы в пользу размещения каких-либо слоев на компьютере клиента состоят в повышении быстроты реагирования (responsiveness) приложения и в обеспечении возможности локальной работы. Чтобы код сервера смог отреагировать на действия, предпринимаемые пользователем на клиентской машине, требуется определенное время. А если пользователю необходимо быстро опробовать несколько вариантов и немедленно увидеть результат, продолжительность сетевого обмена становится серьезным препятствием. Помимо того, приложению требуется сетевое соединение как таковое. Может быть, в обозримом будущем так и случится, но что делать жителям какой-нибудь Тмутаракани, которые не желают ждать, пока кто-то из операторов беспроводной связи удосужится обеспечить "покрытие" их Богом забытого селения. А поддержка возможностей локального функционирования выдвигает особые требования, но боюсь, что они выбиваются из контекста этой книги.

Taking into account all these considerations, you can explore alternatives, considering layer by layer. It is better to always place the data source layer on the server. An exception is the case when server functions are duplicated in the code of a "very thick" client to provide means of local system operation. It is assumed that changes made to separate data sources on the client machine and on the server are subject to synchronization through the replication mechanism. However, this is a topic for another course.

Решение о том, где должен функционировать слой представления, большей частью зависит от предпочтений в выборе типа пользовательского интерфейса. Применение интерфейса толстого клиента автоматически влечет за собой необходимость размещения слоя представления на клиентской машине. Использование Web-интерфейса означает, что логика представления сосредоточена на сервере. Существуют и исключения, например удаленное управление клиентским программным обеспечением (таким, как Х-сервер в UNIX) с запуском Web-сервера на настольном компьютере, но они редки.

Если речь идет о создании системы типа "поставщик-потребитель" ("business to customer" — В2С), у вас просто нет выбора. К серверу может подключиться любой, и вы вряд ли будете мириться с потерей посетителя только из-за того, что он использует какоето экзотическое программное или аппаратное обеспечение. Поэтому целесообразно все функции сконцентрировать на сервере, а клиенту передавать материал в формате HTML, полностью готовый для воспроизведения с помощью Web-обозревателя. Подобное архитектурное решение ограничено в том, что реализация самой незначительной логики пользовательского интерфейса требует обращения к серверу, а это не может не сказаться на быстроте реагирования приложения. Уменьшить зависимость от сервера можно за счет применения фрагментов кода на языках сценариев Web-обозревателя (подобных JavaScript) и загружаемых аплетов, но подобные меры снижают уровень совместимости обозревателей и вызывают другие проблемы. Чем более "чист" код HTML, тем проще жизнь.

Вряд ли ваша жизнь будет простой даже в том случае, если каждый из настольных компьютеров вашей компании настроен, как утверждает начальник отдела информационных технологий, "максимально тщательно". Необходимость поддержки клиентского программного обеспечения в актуальном состоянии и требование исключить даже малую вероятность его несовместимости с другими программами - это серьезные проблемы, которые проявляются и в тривиальных ситуациях.

The main reason for using fat client interfaces is the complexity of the tasks and the impossibility of creating full-fledged useful applications of a different architecture. However, the popularity of Web interfaces is growing steadily, and the need to use fat clients, by contrast, is declining. I can say one thing: use Web-interfaces, if you can, and contact the tools of a fat client, if you can not do without them.

And what about the code of business logic? It can be activated either entirely on the server, or completely in the context of the client side, or using a mixed style. And again the option "everything on the server" is the most attractive from the point of view of the ease of system maintenance. The transfer of any business functions to the client may be due only to, say, the need to increase the responsiveness of the system interface or the need for tools to support local operation.

Если в рамках клиента необходимо выполнять какие-либо функции логики предметной области, прежде всего уместно рассмотреть возможность поручения клиенту всех таких функций. Подобный вариант очень похож на выбор интерфейса толстого клиента. Запуск Web-сервера на клиентской машине ненамного повысит быстроту реагирования приложения, хотя даст возможность использовать его в локальном режиме. Где бы ни находился код бизнес-логики, его следует сохранять в отдельных модулях, не связанных со слоем представления, используя одно из типовых решений - сценарий транзакции (TransactionScript) или модель предметной области (Domain Model). Передача клиенту всего кода бизнес-логики сопровождается - и это уже отмечалось - усложнением процедур обновления системы.

Расщепление множества бизнес-функций между сервером и клиентом выглядит как наихудшее решение, поскольку в общем случае затрудняет идентификацию того или иного фрагмента логики. Основная причина, побуждающая применять подобную архитектуру, может состоять в том, что клиенту необходимо владеть только какой-то частью бизнес-логики. Главное - изолировать эту порцию кода в отдельном модуле, не зависящем от других частей системы. Это даст возможность активизировать код и на компьютере клиента, и на сервере, если такая потребность возникнет позже. Такой подход, разумеется, требует дополнительных усилий, но они оправданны.

После выбора узлов обработки необходимо попытаться обеспечить выполнение всего кода, относящегося к каждому отдельному узлу, в рамках единого процесса, функционирующего либо на одном узле, либо в пределах кластера из нескольких узлов. Не стоит делить слои по разрозненным процессам, если в этом нет насущной необходимости. В противном случае вам придется иметь дело с решениями типа интерфейса удаленного доступа (Remote Facade) и объекта переноса данных (Data Transfer Object), а это чревато потерей производительности и повышением сложности.

Важно помнить, что подобные вещи относятся к числу тех, которые часто называют катализаторами сложности (complexity boosters): это распределенная обработка, многопоточные вычисления, сочетание радикально различных концепций (например, "объектной ориентации" и "реляционной модели"), межплатформенное взаимодействие и обеспечение предельно высокого уровня быстродействия. Решение любой из названных задач сопряжено с большими затратами. Конечно, иногда приходится их нести, но это должно рассматриваться как исключение, а не правило.

created: 2014-10-05
updated: 2024-11-14
399



Rating 9 of 10. count vote: 2
Are you satisfied?:



Comments


To leave a comment
If you have any suggestion, idea, thanks or comment, feel free to write. We really value feedback and are glad to hear your opinion.
To reply

Object oriented programming

Terms: Object oriented programming