Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to break apart layers in a strict-layered architecture and promote modularity without causing unnecessary redundancy? [closed]

Tags:

I've received the go-ahead to start building the foundation for a new architecture for our code base at my company. The impetus for this initiative is the fact that:

  • Our code base is over ten years old and is finally breaking at the seams as we try to scale.
  • The top "layers", if you want to call them such, are a mess of classic ASP and .NET.
  • Our database is filled with a bunch of unholy stored procs which contain thousands of lines of business logic and validation.
  • Prior developers created "clever" solutions that are non-extensible, non-reusable, and exhibit very obvious anti-patterns; these need to be deprecated in short order.

I've been referencing the MS Patterns and Practices Architecture Guide quite heavily as I work toward an initial design, but I still have some lingering questions before I commit to anything. Before I get into the questions, here is what I have so far for the architecture:

(High-level)

High-level

(Business and Data layers in depth)

Business and Data layers in depth

The diagrams basically show how I intend to break apart each layer into multiple assemblies. So in this candidate architecture, we'd have eleven assemblies, not including the top-most layers.

Here's the breakdown, with a description of each assembly:

  • Company.Project.Common.OperationalManagement : Contains components which implement exception handling policies, logging, performance counters, configuration, and tracing.
  • Company.Project.Common.Security : Contains components which perform authentication, authorization, and validation.
  • Company.Project.Common.Communication : Contains components which may be used to communicate with other services and applications (basically a bunch of reusable WCF clients).
  • Company.Project.Business.Interfaces : Contains the interfaces and abstract classes which are used to interact with the business layer from high-level layers.
  • Company.Project.Business.Workflows : Contains components and logic related to the creation and maintenance of business workflows.
  • Company.Project.Business.Components : Contains components which encapsulate business rules and validation.
  • Company.Project.Business.Entities : Contains data objects that are representative of business entities at a high-level. Some of these may be unique, some may be composites formed from more granular data entities from the data layer.
  • Company.Project.Data.Interfaces : Contains the interfaces and abstract classes which are used to interact with the data access layer in a repository style.
  • Company.Project.Data.ServiceGateways : Contains service clients and components which are used to call out to and fetch data from external systems.
  • Company.Project.Data.Components : Contains components which are used to communicate with a database.
  • Company.Project.Data.Entities : Contains much more granular entities which represent business data at a low level, suitable for persisting to a database or other data source in a transactional manner.

My intent is that this should be a strict-layered design (a layer may only communicate with the layer directly below it) and the modular break-down of the layers should promote high cohesion and loose coupling. But I still have some concerns. Here are my questions, which I feel are objective enough that they are suitable here on SO...

  1. Are my naming conventions for each module and its respective assembly following standard conventions, or is there a different way I should be going about this?
  2. Is it beneficial to break apart the business and data layers into multiple assemblies?
  3. Is it beneficial to have the interfaces and abstract classes for each layer in their own assemblies?
  4. MOST IMPORTANTLY - Is it beneficial to have an "Entities" assembly for both the business and data layers? My concern here is that if you include the classes that will be generated by LINQ to SQL inside the data access components, then a given entity will be represented in three different places in the code base. Obviously tools like AutoMapper may be able to help, but I'm still not 100%. The reason that I have them broken apart like this is to A - Enforce a strict-layered architecture and B - Promote a looser coupling between layers and minimize breakage when changes to the business domain behind each entity occur. However, I'd like to get some guidance from people who are much more seasoned in architecture than I am.

If you could answer my questions or point me in the right direction I'd be most grateful. Thanks.


EDIT: Wanted to include some additional details that seem to be more pertinent after reading Baboon's answer. The database tables are also an unholy mess and are quasi-relational, at best. However, I'm not allowed to fully rearchitect the database and do a data clean-up: the furthest down to the core I can go is to create new stored procs and start deprecating the old ones. That's why I'm leaning toward having entities defined explicitly in the data layer--to try to use the classes generated by LINQ to SQL (or any other ORM) as data entities just doesn't seem feasible.

like image 444
Jacobs Data Solutions Avatar asked Feb 07 '12 18:02

Jacobs Data Solutions


People also ask

What is strict layered architecture?

The layered architecture is a classical software architecture that is commonly used in Web, enterprise and desktop applications. In this architecture, the concerns are separated into a stack of well-defined layers. A strict layered architecture only allows to couple to the layer directly below.

What are the different layers of layered architecture?

Although the layered architecture pattern does not specify the number and types of layers that must exist in the pattern, most layered architectures consist of four standard layers: presentation, business, persistence, and database (Figure 1-1).

What is layered architecture What are the benefits of having layered architecture?

Advantages and DisadvantagesThe framework is simple and easy to learn and implement. There is reduced dependency because the function of each layer is separate from the other layers. Testing is easier because of the separated components, each component can be tested individually. Cost overheads are fairly low.

Which one of the following statement is correct in layered architecture?

Which of the following is true with respect to layered architecture? Explanation: Each layer is allowed to depend on the layer below it being present and correct. A layer may call other layers above and below it, as long as it does not use them.


1 Answers

I would disagree with this standard layered architecture in favor of a onion architecture.

enter image description here

According to that, I can give a try at your questions:

1. Are my naming conventions for each module and its respective assembly following standard conventions, or is there a different way I should be going about this?

Yes, I would agree that it is not a bad convention, and pretty much standard.

2. Is it beneficial to break apart the business and data layers into multiple assemblies?

Yes, but I rather have one assembly called Domain (usually Core.Domain) and other one called Data (Core.Data). Domain assembly contains all the entities (as per domain-driven-design) along with repository interfaces, services, factories etc... Data assembly references the Domain and implements concrete repositories, with an ORM.

3. Is it beneficial to have the interfaces and abstract classes for each layer in their own assemblies?

Depending on various reasons. In the answer to the previous question, I've mentioned separating interfaces for repositories into the Domain, and concrete repositories in Data assembly. This gives you clean Domain without any "pollution" from any specific data or any other technology. Generally, I base my code by thinking on a TDD-oriented level, extracting all dependencies from classes making them more usable, following the SRP principle, and thinking what can go wrong when other people on the team use the architecture :) For example, one big advantage of separating into assemblies is that you control your references and clearly state "no data-access code in domain!".

4. Is it beneficial to have an "Entities" assembly for both the business and data layers?

I would disagree, and say no. You should have your core entities, and map them to the database through an ORM. If you have complex presentation logic, you can have something like ViewModel objects, which are basically entities dumbed down just with data suited for representation in the UI. If you have something like a network in-between, you can have special DTO objects as well, to minimize network calls. But, I think having data and separate business entities just complicates the matter.

One thing as well to add here, if you are starting a new architecture, and you are talking about an application that already exists for 10 years, you should consider better ORM tools from LINQ-to-SQL, either Entity Framework or NHibernate (I opt for NHibernate in my opinion).

I would also add that answering to as many question as there are in one application architecture is hard, so try posting your questions separately and more specifically. For each of the parts of architecture (UI, service layers, domain, security and other cross-concerns) you could have multiple-page discussions. Also, remember not to over-architecture your solutions, and with that complicating things even more then needed!

like image 179
Denis Biondic Avatar answered Oct 08 '22 20:10

Denis Biondic