So far we have been building a loan processing software implementation. Now let us introduce another functionality to our software. Let us assume that our bank (surprisingly!) wants to do financial background checks for the customers to whom it is offering the loan. We want to build the new software in a way that in a way that separate application and middle-ware solution, based on the principle of keeping things small (class, module, application, middleware).
Making things smaller means that every piece is easier to understand but at the same time it introduces interaction overhead. If we put every class in its own module, every module in its own application, then that system is not easy to develop or operate. On other if all the classes in a large system are in single application and which has only one module then that system is hard to develop on and may have performance issues. The art is to find the right level of granularity for these. This section and the section on modules would examine the constraints and design ideas on this subject.
Since we decide that we want the separation between the two applications, we pose new and interesting questions for ourselves. These questions need to be answered before we start writing single line of code and re-factoring it be hard (not to suggest that it can be completely avoided). Now we need to make following choices:
A new codebase?
Code reuse between these two applications?
Same database or a different one?
Separate out only the middle-ware or also the presentation layer?
Do we need transaction between the two applications? Depending on the choice the user experience would be determined.
Are the users of both the application same? Do I need single-sign-on?
Should I separate out presentation and services layer of existing application, create new service for new
Escaping Conway's law.
The software architecture of a system is the set of structures needed to reason about the system, which comprise software elements, relations among them, and properties of both.
Application software is computer software designed to help the user to perform singular or multiple related specific tasks.
Multi-tier architecture (often referred to as n-tier architecture) is a client–server architecture in which the presentation, the application processing, and the data management are logically separate processes. For simplicity we would call the data management softwares as data sources.
<<diagram here>>
Another way of understanding such architectures is to look at the logical layers in such systems. Domain driven design (DDD) approach lays it out quite clearly and there isn't a need to look elsewhere at this point. A simple layered architecture would have Presentation, Application, Domain and Infrastructure as its four layers. Since in this context we are enumerating the layers which we develop it doesn't include data management software as a layer.
Application Encapsulated Service and Service Oriented Architectures
In practice web applications may be two-tiered or three-tiered. This results in two kinds of web applications self-sufficient application and presentation application. In three tier architecture presentation applications are served by a middleware tier. These result in two types of architectures which we would refer as application encapsulated service and service oriented architectures.
This choice is really applicable when it doesn't involve rich client applications. The choice of rich client user interface forces one to separate out presentation tier from the rest. This separation means that one really is using service driven approach. This distinction is important because most applications we are building today are web applications. Arguably in case of such applications as well, one still has a separate presentation tier. Sometimes this tier running in the browser is treated as the fourth tier running JavaScript. In-fact with web browser becoming the standard user interface and gaining in capabilities like HTML 5, we can build JavaScript based applications and move the complete presentation layer into the browser.(picture required). If that happens we can treat them as rich client applications delivered over web and running in web browser.
If we leave aside rich client applications then we still have two useful ways of organizing the logical layers into tiers.
Service oriented
In this approach the middleware tier implements application, domain and infrastructure layers of the layered architecture. This also results in pure presentation tiered applications each using one or multiple middleware tiers. These applications have presentation and application proxy layer implemented in them.
Application encapsulated service
In this style we the application hosts all the logical layers of layered architecture. When an application needs to functionality provided by other applications, it directly calls them. Since these applications are web applications they can interact with each other using REST. For the application receiving the request it is like just another request which can be serviced without involving all elements of its presentation layer.
<<diagram here>>
Shared Data and Owned Data Architectures
A large system can consist of multiple data sources. A data source is a logical unit of data elements which are accessible to each other for querying or constraints, independent of the physical nature of the software. e.g. Schema in Oracle. A data source may or may not be directly used by more than one applications or middleware implementations. This distinguishes two types of architecture namely Shared Data or Owned Data.
Owned data
The data source has an owner which is either a middle-ware implementation or self-sufficient application. Other applications or middleware call the owner to access its data. They do access the data directly even for reading.
Shared Data
Shared Data applies the approach of single data source is used by multiple middlewares and applications directly.
Architectural Goals
Reuse
Within an enterprise a software capability is likely to be required by multiple agents (middle-ware or applications) with minor variations. This implies collaboration between various software elements. These core capabilities can be locked inside multiple applications used in the enterprise and a new application cannot reuse them. This can be attributed to technical difficulty. The capabilities which are built into rich client applications are hard to reuse for technical reasons. Most applications being delivered over the web makes such capabilities technical feasuble. But the technical difficulties are not the only one here. The constraint arises from the fact that these capabilities were not modeled over the actual business process, but they rather abstract a single territory of the problem. Even if we could somehow manage to leverage the capabilities spread across multiple applications, it is quite likely that these applications use different data sources. The de-fragmentation of data across the enterprise further reduces their ability to develop meaningful software system.
SOA was in response to such issues and it rightly professed putting these business capabilities at the center of the architecture and applications on the periphery. Enterprise system should consist of software services which can be used by various applications. The boundaries of these services would also determine the data ownership and abstraction. The applications should be very dumb in terms of their knowledge of business. Instead they would depend on these services to.
But there is a flip side of this story as well. I would call it "one app per service". A system which has all its capabilities present in services and utility in applications might suffer from too little re-use of most the services. Horizontally partitioning the layers of your architecture into separate tiers comes at a price of development and deployment. Such systems can be built as a group of web applications interacting with each other. Such applications are technically capable of reuse and if they use layered architecture approach then they can be reused with ease. But choosing to go with application encapsulated services may not work when there are no single natural application which can own a service.
One app per service and widely reused services are two extremes situations and hence a choice of architecture style between them is an art.
Scalability
Evolution
Encapsulating services within an application also couples the deployment of application and service to each other. This can potentially increase the effort in building and testing such applications. A well built automation suite can allay such pains.
Performance
Other notes
A system consists of multiple applications, middleware implementations and databases. It is used by end-users and external systems, which we call jointly as system users. External systems can use the system by interacting with applications, middleware or databases. A system user can use more than one application or middleware.
<<diagram here>>
Chapters
How many services?
Do not reuse the application service operation from another application service. Since the service is published it might be harder to change.
When doing service oriented architecture within an enterprise it might sometimes make sense to provide the client along with the server. Something which implements caching, complex protocol. (CAS, RefDaService)
Cached aggregates when caching on the client
Architecture Patterns presentation
Pluggable application
Host application and plugins.
Do the plugin need to participate in same transaction?
Level of integration: application service and web based. Higher is preferred but not feasible all the time.
Other concerns like remote call cost, knowledge of domain, etc are same as smaller application concerns.
configuration as domain
Why OSGi is not needed?
Batch service requests
Source control structure for modules, applications etc.
Smaller applications
Deployment patterns: Application, Service. Should service layer be separated from presentation layer. Controlling quality of service, application acting as a service, number of database connections.
Different type of tests required when building server applications with their intentions. e.g. test domain behavior which is not easy to predict in isolation.
Distinction between value objects and data objects (data objects need not be transfer objects).
Structure should act as documentation should make it easy to find code. Domain or layer or both. Discuss and decide.
http://www.infoq.com/articles/100SOAQuestions
http://www.martinfowler.com/articles/consumerDrivenContracts.html
Domain and infrastructure based modules
Cross service/application joins (Owned data)
Pluggable architecture
Service/Application configuration
Caching (Topics: reference, configuration, watermark pattern)
Cross service transaction
Service is a verb or noun
Sriram's presentation: Composite Application
Why use modules instead of package structure
Using service layer for data migration
Using service for performance testing: for volume, emit native by running one against service and replace the values.
Run performance test in every build in a single run mode