Four Layer Architecture Discussion

Is FourLayerArchitecture actually a pattern? Does it really work? I suspect that the DomainLayer? is a nice idea but an Employee in application X is most likely different to an Employee in application Y. A domain layer as proposed (and really proven to work?) is probably feasible with a subject-oriented programming approach but I have my doubts for current object-oriented technology. -- ThomasKuehne (mailto:T.Kuehne@soc.staffs.ac.uk)

KB -- This isn't a theoretical pattern. I've used this architecture in God only knows how many projects (>>100!) As you can gather from the comments in TooMuchGuiCode, it's a fairly common abstraction. It doesn't depend on Employee being the same in applications X and Y - the key is that the Employee doesn't do GUI's, and doesn't do Database stuff - he just acts like an Employee.

Really? Many more than 100 projects! This requires that you completed over three projects a year for 30 years, less than 4 months a project at a sustained rate.


I don't see why the "Infrastructure layer" is a layer, rather than a module or group of modules. It sounds almost like a "Collections layer" or "Mathematics layer". Sure, it makes sense to have a package of reusable classes for dealing with mathematical issues, that is specific to neither the application nor the application's domain. It wouldn't be a layer though. -- DaveHarris

KB -- If you've ever worked with a relational database mapping product like TOPLink then you'd see that this most certainly *is* a layer. There's a *lot* of stuff that goes on in there. I've done similar projects that utilized Brokers working with 3270 screens and LU6.2 connections - in each case there are responsibilities that are distinct from the domain objects - thus necessitating another layer.


The "Infrastructure layer" can certainly be viewed as a layer when considered from a resources & responsibility perspective. A person or group of people is given the job of creating support frameworks, objects and behavior so generic that they are reuseful beyond the scope of the application(s) being built. -- Carl Gundel (mailto:carlg@world.std.com)


I seems like there should be a fifth layer (if not practically of any great importance, at least conceptually). The applicationModel layer above is closely linked to the UI. One could think of this layer as more of a viewManager layer, i.e. its job is to manage the interface. Since the domain layer should theoretically contain objects that are not application-specific, there needs to be another layer in-between these two that contains application-specific objects that are not related to the UI - i.e. objects that implement core application functionality, but specific to the application. These objects would typically include objects such as coordinators, mediators, controllers, etc. Many architectures assume that the user directly manipulates domain objects - not always true! Sometimes, a user operates a software "machine" that in turn manipulates the domain objects. There is a logical layer between the user and the domain.

In the five-layer architecture, one has absolute separation of the UI and underlying application logic - one could conceivably throw away the top two layers and run the application programmatically just as a user would.

Does this have any merit? Comments encouraged.

-- Wayne Madgett (mailto: madgett@sr.hp.com)

KB - yes it does have merit! In fact, I've come to the same conclusion myself that in some cases (not all, though) that breaking up the Application Model layer into two additional layers (which I call the Mediator and Facade layers) is a useful trick. See the following paper that I wrote about that for more information: http://members.aol.com/kgb1001001/Articles/D-ICM/d-icm.htm

TS - Similar approach in EJB Design Patterns by Floyd Marinescu

  1. Presentation
  2. Application
  3. Services
  4. Domain
  5. Persistence
Note that workflow is split into application (in 2) and business (in 3) - they can be very different. Also, layer 3 controls Txns - thus removing them from the application. Finally (here) test automation is much easier by driving layer 3 objects


Separation of the UI and underlying application logic...

commonly known in the form of undo mechanisms.

Actually, for a fully-functional undo mechanism you also have to represent operations in the domain layer in object form; rather than calling operation methods directly on the domain objects.

Wrapping method calls & their parameters into objects, allows these to be kept in an undo log for undo & redo. The best approach is to architect these domain operations as reversible primitives of various simple state-changes on the domain object.

These primitives have to embody the fundamental duality of operations; an operation is a transition between two states, before and after. This transition can be executed in either direction; backwards for undo, forward for redo & to perform the operation in the first place.

These primitives can in some architectures be driven directly from the controller layer, but in other circumstances some higher-level domain functionality might be placed above the undo design. However I'm unsure as to the architectural desirability of such delta logging schemes... ?

The point of interest, when you actually come to implementing one of these, is stability of identifiers when you've deleted & recreated an object; then try to apply changes to it.

Are GUIDs really the answer??

-- ThomasWhitmore


The Infrastructure Layer

In UML Use Cases, the Actor can be a person or another computer. Why not another program, on this computer.

I use this a lot. Make the first design step writing the use cases for a package or object. The actors represent the software roles that will use it. E.g. a UsableDate? class would have two actors: the actor that needs a date service and the actor that keeps the correct time.

The use cases need to be specific to the project so you don't waste time realizing useless cases.

In other words, the things in the Infrastructure layer just appear to me to be Actors. A Data base is an actor, and when you ask it for data, just as you ask an operator to fill in a field, it does so. Also, databases have their own lives and may be serving other programs at the same time, so they need not be part of this program.

Further, when I try to use a database, I have interfaces or APIs. Now these are part of this program, just as much as the graphical interfaces or GUIs. In fact both GUIs and database APIs have two interfaces layers. GUIs have the normal requests of 'display this' etc and they have callbacks (Interrupts or events), that occur when the user carries out an unrequested action. Database APIs also have two interface layers, one for the CRUD or SQL functions and the other for dealing with database triggers, that are unrequested actions.

Finally, the API is likely to be database specific and so the connections to the Business (Domain) objects will be dependent on the data base. If however, there was an 'Application Layer' between the domain and database APIs, to cover this, then the analogy is complete. The domain layer sits in the middle with an 'Application layer' on each side. The GUI is at one extreme linking to actors who are real people and the API is at the other extreme linking to actors that are databases.

For simplicity, this could be folded, so that the actors of all kinds work through an Interface(GUI or API) Layer into Application Layer that sorts out the way the domain objects are used. Also, the Interface layer in both cases has two parts, one to cover the program driven interactions and the other to deal with interrupts.

This returns us to a three-layer architecture that is different from the conventional one. This then maps back to the MVC model, because the Domain Lyer is the model, the Interface layer is the 'View' layer and the Controller layer is the 'piggy in the middle' whose job it is to house all the knowledge of how to use the domain objects and the interfaces. This is the bit that contains the code that may have to be rewritten if the database changed, or we swopped from a java Swing GUI to web pages etc. It alos make the 'Robustness checks' almost simplistic: 'No objects in the Interface Layer may connect directly to any object in the Domain Layer.'

-- Gil Rooke

mailto: gil.rooke@btopenworld.com


Application Layer

I have come across another idea, that seems to work in simple architectures at least.

The control objects should just be, at least in the first cut of the design, the use cases. A use case is really just a communications protocol between the actor and the domain. Its key feature is that the user does something and and the system responds. So this controller must know what the user does. It then decides which domain objects are interested this event and, using the sequence diagram, gets their response, which it passes back to the interface.

On less firm ground now, I also see strong resemblances between the Application Layer (Controller or Use Case Implementation) and the java enterprise Session Bean. The domain class is the entity bean.

-- Gil Rooke

mailto: gil.rooke@btopenworld.com


I always have tried to use a 4-layer architecture as described here. In the ideal case, one layer would just have to use the next one. The only problem though is with the Infrastructure layer, in that it usually needs to be used by all the other layers. For example, I often find that the elements from the GUI-layer have to insert information in a database so the objects in the other layers could retrieve them for their purposes. -- RichardSmol

Very good point. I often find that "exposing" the infrastructure layer a little bit is necessary. For instance, in many cases it should be the ApplicationModel Layer that should control the beginning and end of database transactions (yes I know that's not the EJB Way, so sue me!) So a related idiom is DontBeTooStrictAboutLayering. -- KyleBrown


In general, I agree that one can't be totally strict about layering. However, I do feel that in the case cited above involving the GUI layer inserting directly into the database via the infrastructure layer, it would be preferable to have a layer in between that provides that as a service. The reason I like this approach is that it minimizes the amount of dependencies between the layers, i.e. what is hidden behind a layer is hidden, reducing coupling in the system. This is most useful in large enterprise systems that live a long time.

-- TimSeltzer


Very good point! A ServicesArchitecture? is truly the best way to hide these dependencies - but as you hint, they're a bit challenging to build. RandyStafford is working on some ideas here - maybe he'll contribute...

KyleBrown

Well, I tried to describe my ideas about service-based architecture and service layers in Chapter 7 of EjbDesignPatternsBook and in Chapter 9 of PatternsOfEnterpriseApplicationArchitecture. Fundamentally I think what's happened over the years as we've evolved from two-tier fat-client architectures (which used FourLayerArchitecture), to distributed-object application-server-based architectures, is that a fifth (and maybe sixth) layer of architecture has become necessary. Responsibilities that used to be allocated to the client-side application layer (i.e., coordinating the system's transactional response to an external stimulus) are now allocated to a (new) server-side service layer that forms an ApplicationBoundary. DataTransferObjects, furthermore, can be thought of as defining a sixth ("distribution") layer. So the layer stack in a canonical J2EE app with web container remote from EJB container is now presentation, application, distribution, service, domain, persistence (infrastructure). The application layer runs in the web container while the service and domain layers run in the EJB container. The presentation layer runs in the web browser and partly in the web container. The distribution layer kind of spans the web and EJB containers, and the persistence layer spans the EJB container and database. Co-locating the web and EJB containers (desirably) eliminates the distribution layer, but even then it still makes sense to separate the service and application layers, IMHO, because they have different responsibilities. -- RandyStafford


I've used this kind of approach in several of my projects. I had a different naming convention, though. Here are my layers:

  1. Presentation Layer (deals with GUI)
  2. Application Layer (deals with application specific dependencies)
  3. BusinessRules Layer (deals with the business rules of the underlying application)
  4. DataServices? Layer (deals with persistent Data, Communication with legacy applications for information, Enterprise-specific storage restrictions).

What I achieved by the above approach is I was able to replace one or more of the layers with the appropriate implementations. For example, After finishing one of my projects (for internet users), I replaced my Presentation layer and Business Services layer to create another application (for intranet users) which deals with new/additional set of business rules. I was able to reuse a lot of the stuff I've created.

However I was happy to see this article as I found that the approach I used is not far from others.

-- Sarma Chirravuri


The latest incarnations of the Microsoft MSDN Duwamish Books sample app uses a 4 layer architecture with the following layers: (this could just be semantics)

Presentation Layer (PL) Workflow Layer (WFL) Business Logic Layer (BLL) Data Access Layer (DAL)

The workflow layer mediates between the PL and the BLL, the BLL has sole access to the DAL, the PL only talks to the WFL, etc. (the knee bone's connected to the leg bone...)

As this sample has progressed, it has gone from desktop app to 2 tier to 3 tier to web app.

It might be worth looking at to see how well the 4 layer notion has worked in reality.

What do you mean by "in reality"? -- this whole pattern was based on having done this multiple dozens of times -- KyleBrown

Dan Bush


This breakdown strikes me as being very similar to ModelViewPresenter. The "View layer" corresponds to MVP's View. The "Application Model layer" roughly corresponds to MVP's Presenter. The "Domain Model layer" corresponds to MVP's Model.

One difference is that MVP is not really about layers. The View is not "on top of" the Model. Arguably the Presenter is "on top of" the other two, but this image is hard to sustain when we apply the pattern recursively, with big Presenters being composed of several smaller ones.

Another difference is the "Infrastructure layer". I still don't grock this part - to me it is just that some modules are more reusable than others - so I don't want to comment on where infrastructure goes to in MVP. -- DaveHarris

It doesn't. These are different abstraction dimensions. Infrastructure is the bottom layer in the System Architecture, not Application Architecture (assuming a layered Application Architecture, which is by no means essential). The System Architecture is orthogonal to the Application Architecture which is why people get so confused about what to do with the UI. The solution is that the UI logic lives in the Presentation Layer (the top Application Layer), while the GUI API is part of the I/O Services Layer (next to the bottom of the System Architecture). The Presentation Layer code (View in MVC) talks sideways to the GUI API.

The single essential feature of a layer, the one that makes it different from everything else in the universe, is that it creates two sets of code that talk only with the layer and never with each other. If that's not what's happening, you have a component, not a layer. We all know how gratifying it is to say that our application uses a "layered architecture"--even our most non-technical managers are impressed by how clever we are and how this will make our application robust, easy to maintain and on-time and under-budget. But you and I know it's really a component architecture.


I've seen two reasons why people don't grok the Infrastructure layer:

(1) They don't use real DomainObject classes. I've seen many people who have programmed in an OO language for years and have never written a domain object in their life -- with a resulting loss of reusability and potential for refactoring.

(2) They don't see a problem with tying a DomainObject directly to its datasource. If this is the only disagreement, then there is something to be said for not having an infrastructure layer. However, I've often gone into projects after having seen them built like this only to see them founder when the second set of datasources emerges. Thus the Infrastructure layer idea...

-- KyleBrown


See http://virtualschool.edu/wap for several articles and Java code for such an architecture. In particular, see the "The Problem" article, which engages the question of what it means to "separate" things. On separate machines? In html (template) files versus the running code (application)? Most environments use dynamic binding to interface these layers. The articles describe benefits of connecting things more tightly, for example by maintaining views in separate *methods* (so static typechecking can validate links) as distinct from in separate *files* (as template languages do). And how template languages can be inserted for those cases where only dynamic binding will do; for example to coexist with html designers and tools that insist that html belongs in files. -- BradCox


They don't use real DomainObject classes Can you elaborate a little more? I've ostensibly been doing OO development for years, but I'm still waiting on that AhaMoment when it all falls into place.

It's taken almost two years to respond to this, but yes, now I can point you to somewhere where there is significant elaboration. It turns out that this wasn't the only place where this question was asked -- much to the surprise of the Smalltalk community, where we all knew what domain objects were. First, go to http://www.domainlanguage.com/ and download and read Eric's book. He explains what they are and how they work much better than I ever could. Then go to http://www.martinfowler.com/isa/ and find out how the domain modeling fits into a larger architecture. FourLayerArchitecture was just the first, briefest glimpse at what I really meant. Martin and Eric truly explain it. -- KyleBrown

And one thing I don't get about the Infrastructure layer - who tells it what to do? Who says, "read the state of this object" or "I'm done, commit your transaction now." -- EddieDeyo


I often use variants of the FourLayerArchitecture in my projects. I think the reason people are having a difficult time grocking the infrastructure layer is that it is actually two layers. There are the reusable objects and libraries such as Collections, Containers, Math and XmlParser?. Then there is what I call the platform layer - Database, OS-specific capabilities (yes, including OS-specific GUI). The SeparationOfConcerns between the layers is crucial, but the emerging structure is more like a graph. I also treat the Model as a dumb data store that provides several access interfaces (some objects just need to read some data from the model, others have to manipulate it), and the actual manipulation of the model is done in the so-called engine layer.

-- GigiSayfan


I HaveThisPattern; I find it helps explain it if we say that the application model layer contains things that you want to do and the domain model layer contains the things that you want to do them to! For example, a banking application might have Customer and Account in the domain layer and things like CreateAccount, TransferFunds and DepositCheque in the application layer. Another way of thinking about this is that the things in the domain layer should be more reusable than the things in the application layer - if I'm going to write a new application for writing statements and mailing them to customers, I would be able to reuse Customer and Account, but I'd have to write a bunch of new application objects.

The role of the domain objects is obvious to most people, but I think the application objects need more explaining; I don't understand them fully myself. Their roles include:

I find the application/domain split maps (at least in theory) quite well onto the session/entity distinction in EJB. Yes, and application objects can map to UseCases.

-- TomAnderson

How does this pattern interact with AlternateHardAndSoftLayers? It would seem that the lower layers need progressively harder languages; operating systems, databases, transaction monitors, etc, are usually implemented in C, but java seems better for business objects, and perhaps a yet lighter scripting language would be appropriate for the structurally simple and rapidly changing application objects. GUIs and web interface are often implemented in systems that are not even real programming languages - forms designers and HTML templates. -- TomAnderson

The View layer. I have found the most success, personally, by coupling the view and controllers as loosely as possible, particularly in the first iterations of the project. By organizing packages around the use case realizations, I am able to put the views' business methods in RUP's boundary class, such that it becomes the first control layer for its associated view(s). I put the business methods in an abstract use case boundary superclass to evaluate application rules. Commands and client-specific implementation details go in the concrete class. I wrap the loose ends up by coding the view(s) as composite(s) of the concrete boundary.

The Application Model layer. I put controllers that know other controllers here and factory out the creation of the boundary class.

The Domain Model layer. To say that most objects found in OO analysis and design reside here and follow up with the objects in this layer can be application-independent evokes a pretty strong objection from me. My bias is to map everything in the system to requirements. As a RUP practitioner, I put entities in this layer. I haven't found the holy grail of the data-driven system and am agnostic, perhaps atheistic, as to its existence. Show me the money!

The Infrastructure layer. Actors that are not workers, right?

mailto: Jeff.Barnes@mnsft.com


Hmm, requirements requirements.

The point of all architecture and design, is to fulfill external requirements.

However, dealing with several similar types of data in an information system, may lead one to abstract features such as load & store data or viewing/ editing form into distinct modules or layers.

I'm going to suggest here that such infrastructure may exist in any part of the application. Specific views may be built on display components or common ancestor forms. Specific domain layers might use collection or data-type (eg rich text) packages. Specific applications might use workflow, event-handling framework or undo packages...

Infrastructure is particularly heavily used in the view layer for GUI development tools. These were the focus of early software framework development, followed by database & persistence technology for the domain layer.

-- TW


I use a similar model to the FourLayerArchitecture. However, the architecture I am using have a DB, a server that has all of the domain logic, and a web gui that interacts with the server. The web gui is out of process, because it is possible for more than one client to connect to the server. So, I end up splitting the application layer into two separate layers: a service layer, and a remote layer. The service layer provides services to clients, abstracts away the domain layer, and provides implicit transaction management. The remote layer basically is a CORBA layer that sits on top of the service layer, receives calls from clients and maps the CORBA objects back to service layer objects.

However, I find that this approach leads to the feeling of code duplication. For every structure I might pass around in CORBA I map to a similar structure in the service layer. This is because theoretically I don't want the service layer or anything below to know about CORBA and I don't really want all of the application logic directly in the CORBA layer. Another thing is that I'd like to use the same name for objects that I pass around via CORBA interfaces and objects in the application layer, but this leads to a lot of confusion about which class to which I am actually referring.

All that said, has anyone else tried a similar architecture? What has been your experience?


It seems that it may be useful to visualize this as a star diagram with DomainLayer at the center of your application's universe. All interfaces are represented as rays off of the DomainLayer. Depending on their complexity or reuse needs, each ray may be separated into two (or more) layers. Since GUIs are a ubiquitous concern, their layers have been codified (ViewLayer, ApplicationLayer). It seems, though, that the InfrastructureLayer is precisely analogous to a condensed ViewLayer/ApplicationLayer, only for non-GUI interfaces.

Presumably, any interface (GUI, DB, terminal, sockets) could be separated into abstraction layers as fits your perceived needs for reuse or ease of refactoring. If this perspective is valid, any discussion of layers could apply to any interface to your DomainLayer. In essence, this would suggest viewing every application as a translation tool, whereby your DomainLayer is your "universal language" to/from which all other data sources (humans, databases, packets, files) must be translated.

Is this a valid perspective?

Rodney.M.Smith SAIC(.com)

Rodney - see HexagonalArchitecture


There is an extensive discussion of

in a paper I wrote with a colleague. See

http://www.ratio.co.uk/architectural_reference_model.pdf

(first published at XP2000).

I'm very interested in any feedback anyone can give on this - please feel free to attack it as much as possible (cc: markcollinscope at gmail dot com please).

Regards, MarkCollinsCope, London, April '05.

The paper doesn't say much new, neither does it communicate much insight. Layering is a well known and time honored principle, but abuse and misunderstanding, is often widespread. I would not chose that as a reference model - too many layers. I'd rather stick with ThreeTierArchitecture as a reference model for I have seen too often that heavy layering leads to madness, like we have with the PetStore example and many real life failures inspired by such architectural guidelines. -- CostinCozianu


I just wrote a reference architecture with 11 layers (6 processing, 5 communications). Do I win :)?

For the time being, yes. Since somebody started HexagonalArchitecture, I'll challenge you to add one more and make it DodecahedralArchitecture?.


(very amusing - last contributor :-)

Costin, thanks for those words of encouragement.

"Layering is a well known and time honored principle, but abuse and misunderstanding, is often widespread."

Well, with all due respect, it seems to me you can't have it both ways. Either everyone knows and understands layering or they don't. *As the paper says*, layering is not a new concept, but there are many takes on it. Just have a look out there! People mix tiers with layers all the time - when they're orthogonal concepts (tiers are about deployment, layers are about decomposing software). You're right that three-tier architecture is a good reference model - but it deals with different issues and concerns. Three-tier architecture is motivated by scalability. Layering is motivated by getting well-factored code and removing duplication and maybe getting some reuse.

The model presented in the paper (originally published in XP Examined, Marchesi and Succi) is based on a specific set of layers (which look superficially like the four layered architecture this page is based on, but are different when you look at the detail).

Specifically the model adds the following that I've not seen anywhere else. Perhaps you can point me in the right direction?

One direction would be DavidParnas. In his book SoftwareFundamentals he has an article dealing at least partially with some of your concerns ("On a buzzword: hierarchical structure"), actually the whole part 2 of the book is very relevant in the context.

I'll come back with more substantive comments later. Suffice it to say for now that there's horizontal decomposition and vertical decomposition of systems architecture. Your article addresses only a horizontal approach. I've seen more systems succeed with a vertical approach, while an application like PetStore while being perfectly layered, fails on so many objective criteria. So we need some objective criteria to quantify architectural decisions. -- Costin

As for too many layers - well, if you ignore Platform and call it Infrastructure - you get four layers as per the discussion on this page. But it seems to me that any serious model for large scale applications needs to specically ["specially" or "specifically"?] address platform components/utilities. And note: because it doesn't follow strict-layering rules, you're not forced to put loads of stuff in just *because* of the layering.

I've used it on three large scale systems now, and it has helped us keep our gross package structure under control, and we've been able to reuse infrastructure stuff across projects.

If you have any *specific* objections or comments re: the paper (or can demonstrate why it is wrong, for example) I'd be happy to address them.

Regards,

MarkCollinsCope


I'd like to go even further in the direction of the previous contributor regarding his points about product-line architecture and the Infrastructure layer and Platform layer. I very much agree with his point, but I usually split the Infrastructure and Platform components into layers. My feeling is that this promotes pluggability of the components responsible for Platform and Infrastructure related tasks.

I think this promotes product-line architecture, because it would be possible to factor code sideways (more application independent, but part of the layer) so that code built for a specific application could lead to patterns and utilities added to layer-specific product-line components.

-- DaveDeVos

For your information - an additional paper on the ARM (architectural reference model) discussed by myself above is: http://www.ratio.co.uk/W13.html (also at http://www.ftponline.com/ea/magazine/summer2005/features/mcollinscope/ ). -- MarkCollinsCope


CategoryArchitecture


EditText of this page (last edited February 26, 2006) or FindPage with title or text search