An architectural style in software consists of a few key features and rules for combining those features so that architectural integrity is preserved.An architectural software style is determined by the following:set of component types (e.g., data repository, a process, a procedure) that perform some function at runtime topological layout of these components indicating their runtime interrelationships set of semantic constraints (for example, a data repository is not allowed to change the values stored in it) set of connectors (e.g., subroutine call, remote procedure call, data streams, sockets) that mediate communication, coordination, or cooperation among components.
Data Centered Architectures Data-Centered architectures have the goal of achieving the quality of integrability of data.The term Data-Centered Architectures refers to systems in which the access and update of a widely accessed data store is an apt description. At its heart, it is nothing more than a centralized data store that communicates with a number of clients. The means of communication (sometimes called the coordination model) distinguishes the two subtypes: repository (the one shown) and blackboard. A blackboard sends notification to subscribers when data of interest changes, and is thus active.
Data-centered styles are becoming increasingly important because they offer a structural solution to illegibility. Many systems, especially those built from preexisting components, are achieving data integration through the use of blackboard mechanisms. They have the advantage that the clients are relatively independent of each other, and the data store is independent of the clients.
Thus, this style is scalable: New clients can be easily added. It is also modifiable with respect to changing the functionality of any particular client because otherwise will not be affected. Coupling among clients will lessen this benefit but may occur to enhance performance.
Data-Flow architectures have the goal of achieving the qualities of reuse and modifiability.The data-bow style is characterized by viewing the system as a series of transformations on successive pieces of input data. Data enter the system and then flows through the components one at a time until they are assigned to some final destination (output or a data store).In the batch sequential style, processing steps, or components, are independent programs, and the assumption is that each step runs to completion before the next step starts. Each batch of data is transmitted as a whole between the steps.
The typical application for this style is classical data processing.
The Pipe-and-Filter style emphasizes the incremental transformation of data by successive components. This is a typical style in the UNIX family of operating systems.
Filters are stream transducers. They incrementally transform data (stream to stream), use little contextual information, and retain no state information between instantiations. Pipes are stateless and simply exist to move data between filters.
Both pipes and alters are run non-deterministically until no more computations or transmissions are possible. Constraints on the pipe-and-alter style indicate the ways in which pipes and alters can be joined.
A pipe has a source end that can only be connected to a filter’s output port and a sink end that can only be connected to a alter’s input port.
Pipe-and-filter systems, like all other styles, have a number of advantages and disadvantages.
Their advantages principally flow from their simplicity-the limited ways in which they can interact with their environment.
This simplicity means that a pipe-and-filter system’s function is no more and no less than the composition of the functions of its primitives.
There are no complex component interactions to manage.
Pipe-and-filter systems advantages:The pipe-and-filter style simplifies system maintenance and enhances reuse for the same reason-filters stand alone, and we can treat them as black boxes.Both pipes and filters can be hierarchically composed: Any combination of filters, connected by pipes, can be packaged and appear to the external world as a filter.
Because a filter can process its input in isolation from the rest of the system, a pipe-and-filter system is easily made parallel or distributed, providing opportunities for enhancing a system’s performance without modifying it.
Pipe-and-filter systems also suffer from some disadvantages.There is no way for filters to cooperatively interact to solve a problem.Performance in such a system is frequently poor for several reasons, all of which stem from the isolation of functionality that makes pipes and alters so modifiable; these reasons are listed below:
Filters typically force the lowest common denominator of data representation (such as an ASCII stream). lf the input stream needs to be transformed into tokens, every filter pays this parsing/unparsing overhead.
If a alter cannot produce its output until it has received all of its input, it will require an input buffer of unlimited size. A sort filter is an example of a filter that suffers from this problem. lf bounded buffers are used, the system could deadlock.
Each filter operates as a separate process or procedure call, thus incurring some overhead each time it is invoked.
Virtual Machine Architecture Virtual Machine architectures have the goal of achieving the quality of portability. Virtual machines are software styles that simulate some functionality that is not native to the hardware and/or software on which it is implemented.This can be useful in a number of ways:It can allow one to simulate (and test) platforms that have not yet been built (such as new hardware), and it can simulate “disaster” modes (as is common in flight simulators and safety-critical systems) that would be too complex, costly, or dangerous to test with the real system.
Common examples of virtual machines are interpreters, rule-based systems, syntactic shells, and command language processors.
Interpretation of a particular module via a Virtual Machine may be seen as follows:
- the interpretation engine selects an instruction from the module being interpreted;
- based on the instruction, the engine updates the virtual machine internal state;
- the process above is repeated;
Executing a module via a virtual machine adds flexibility through the ability to interrupt and query the program and introduce modifications at runtime, but there is a performance cost because of the additional computation involved in execution.
Call-and-Return Architectures Call-and-Return architectures have the goal of achieving the qualities of modifiability and solvability.Call-and-Return architectures have been the dominant architectural style in large software systems for the past 30 years.However, within this style a number of substyles, each of which has interesting features, have emerged.
Main-Program-and-Subroutine architectures is the classical programming paradigm. The goal is to decompose a program into smaller pieces to help achieve modifiability.A program is decomposed hierarchically. There is typically a single thread of control and each component in the hierarchy gets this control (optionally along with some data) from its parent and passes it along to its children.
Remote procedure call systems are main-program-and-subroutine systems that are decomposed into parts that live on computers connected via a network.The goal is to increase performance by distributing the computations and taking advantage of multiple processors. In remote procedure call systems, the actual assignment of parts to processors is deferred until runtime, meaning that the assignment is easily changed to accommodate performance tuning. In fact, except that subroutine calls may take longer to accomplish if it is invoking a function on a remote machine, a remote procedure call is indistinguishable from standard main program and subroutine systems. Object-oriented or abstract data type systems are the modern version of call-and-return architectures.The object-oriented paradigm, like the abstract data type paradigm from which it evolved, emphasizes the bundling of data and methods to manipulate and access that data (Public Interface).The object abstractions form components that provide black-box services and other components that request those services. The goal is to achieve the quality of modifiability.
This bundle is an encapsulation that hides its internal secrets from its environment. Access to the object is allowed only through provided operations, typically known as methods, which are constrained forms of procedure calls. This encapsulation promotes reuse and modifiability, principally because it promotes separation of concerns:
The user of a service need not know, and should not know, anything about how that service is implemented.
Layered systems are ones in which components are assigned to layers to control intercomponent interaction. In the pure version of this architecture, each level communicates only with its immediate neighbours. The goal is to achieve the qualities of modifiability and, usually, portability. The lowest layer provides some core functionality, such as hardware, or an operating system kernel. Each successive layer is built on its predecessor, hiding the lower layer and providing some services that the upper layers make use of. Independent Component ArchitecturesIndependent component architectures consist of a number of independent processes or objects that communicate through messages.All of these architectures have the goal of achieving modifiability by decoupling various portions of the computations. They send data to each other but typically do not directly control each other.
The messages may be passed to· named participants (Communicating Processes style);
· unnamed participants using the publish/subscribe paradigm (Event Style) .
Event systems are a substyle in which control is part of the model. Individual components announce data that they wish to share (publish) with their environment − a set of unnamed components.These other components may register an interest in this class of data (subscribe). If they do so, when the data appears, they are invoked and receive the data.Typically, event systems make use of a message manager that manages communication among the components, invoking a component (thus controlling it) when a message arrives for it. In this publish/subscribe paradigm, a message manager may or may not control the components to which it forwards messages.
Components register types of information that they are willing to provide and that they wish to receive.
They then publish information by sending it to the message manager, which forwards the message, or in some cases an object reference, to all interested participants.
This paradigm is important because it decouples component implementations from knowing each others’ names and locations. As mentioned, it may involve decoupling control as well, which means that components can run in parallel, only interacting through an exchange of data when they so choose. This decoupling eases component integration
Besides event systems, the other substyle of independent components is the communicating processes style. These are the classic multiprocess systems.
Of these, client-server is a well-known subtype. The goal is to achieve the quality of scalability.
A server exists to serve data to one or more clients, which are typically located across a network. The client originates a call to the server, which works, synchronously or asynchronously, to service the client’s request.
If the server works synchronously, it returns control to the client at the same time that it returns data. If the server works asynchronously, it returns only data to the client (which has its own thread of control).
Heterogeneous StylesSystems are seldom built from a single style, and we say that such systems are heterogeneous.
There are three kinds of heterogeneity, they are as follows.
Locationally heterogeneous means that a drawing of its runtime structures will reveal patterns of different styles in different areas.For example, some branches of a Main-Program-and-Subroutines system might have a shared data repository (i.e. a database).Hierarchically Heterogeneous means that a component of one style, when decomposed, is structured according to the rules of a different styleFor example, an end-user interface sub-system might be built using Event System architectural style, while all other sub-systems − using Layered Architecture.
Simultaneously Heterogeneous means that any of several styles may well be apt descriptions of the system.This last form of heterogeneity recognizes that styles do not partition software architectures into non-overlapping, clean categories. You may have noticed this already. The data-centered style at the beginning of this discussion was composed of thread-independent clients, much like an independent component architecture.The layers in a layered system may comprise objects or independent components or even subroutines in a main-program-and-subroutines system. The components in a pipe-and-filter system are usually implemented as processes that operate independently, waiting until input is at their ports, again, this is similar to independent component systems whose order of execution is predetermined.