DDD vs N-Tier (3-Tier) Architecture
Asked Answered
M

4

13

I have been practicing DDD for a while now with the 4 distinct layers: Domain, Presentation, Application, and Infrastructure. Recently, I introduced a friend of mine to the DDD concept and he thought it introduced an unnecessary layer of complexity (specifically targeting interfaces and IoC). Usually, its at this point, I explain the benefits of DDD-- especially, its modularity. All the heavy lifting and under the hood stuff is in the Infrastructure and if I wanted to completely change the underlying data-access method, I could do so with only having to touch the Infrastructure layer repository.

My friend's argument is that he could build a three tiered application in the same way:

  • Business
  • Data
  • Presentation

He would create business models (like domain models) and have the repositories in the Data layer return those Business models. Then he would call the business layer which called the data layer. I told him the problem with that approach is that it is not testable. Sure, you can write integration tests, but you can't write true unit tests. Can you see any other problems with his proposed 3-tiered approach (I know there is, because why would DDD exist otherwise?).

EDIT: He is not using IoC. Each layer in his example is dependent on one another.

Marielamariele answered 30/9, 2010 at 19:1 Comment(2)
Domain-driven design and tiered architecture don't really seem to be relevant to your dispute (and as I understand them, they're orthogonal to one another). If you peel away the acronyms, what are you really disagreeing about? Coding to interfaces and dependency injection?Counselor
"EDIT: He is not using IoC. Each layer in his example is dependent on one another. " can still use Mockito to test. So it's not one or the other. More about what one or a group perceives as cleaner, well designed, and easier to maintain (as a comparative level, not that other would-be completely unmaintainable) codeIny
W
16

I think you're comparing apples and oranges. Nothing about N-Tier prohibits it from utilizing interfaces & DI in order to be easily unit-tested. Likewise, DDD can be done with static classes and hard dependencies.

Furthermore, if he's implementing business objects and using Repositories, it sounds like he IS doing DDD, and you are quibbling over little more than semantics.

Are you sure the issue isn't simply over using DI/IoC or not?

Wherefrom answered 30/9, 2010 at 19:56 Comment(2)
How can something be easily unit tested without using IoC? He can have integration tests, but how would you do unit testing without interfaces/IoC/DI?Marielamariele
what I'm saying is that DDD or N-Tier doesn't imply IoC or not. It seems like you are trying to focus the question on DDD vs. N-Tier, but what your question really seems to be asking is IoC/DI vs. no IoC/DI. fwiw, I'd be on your side supporting IoC/DI. I just don't think DDD or N-Tier are relevant at all, since either can be done with or without DI/IoC.Wherefrom
A
11

I think you are mixing a few methodologies up. DDD is Domain-Driven Developement and is about making the business domain a part of your code. What you are describing sounds more like the Onion Architecture (link) versus a 'normal' 3-layered approach. There is nothing wrong with using a 3-layered architecture with DDD. DDD depends on TDD (TestDriven Developement). Interfaces help with TDD as it is easier to test each class in isolation. If you use Dependency Injection (and IoC) it is further mitigated.

The Onion Architecture is about making the Domain (a.k.a. business rules) independent of everything else - ie. it's the core of the application with everything depending on the business objects and rules while things related to infrastructure, UI and so on are in the outer layers. The idea is that the closer to the 'shell of the onion' a module is - the easier it is to exchange for a new implementation.

Hope this clears it a bit up - now with a minor edit!

Amalgamation answered 30/9, 2010 at 19:18 Comment(7)
Hmmm... I am very familiar with Jeff Palermo's Onion Architecture, as my project has those distinct layers within it and I based it around his blog post. Yet, all of these layers also exist in a DDD project as well (e.g. Domain, Application, Presentation, and Infrastructure).Marielamariele
My point was that although the union structure is used by many who also use DDD - it is not a prerequisite for DDD.Amalgamation
To further elaborate - to practise DDD - you do not need a specific set of layers nor do they need to be structured in a specific way. However, everything you code should model the domain you are targeting including business objects having the same names as their real-life counterparts.Amalgamation
Yet the difference is that within the 3-layered approach I described, without using IoC, is that every layer knows and depends on each other... isn't that an anti-pattern?Marielamariele
It isn't an anti-pattern per se, but I agree that using the onion structure makes the coupling looser as the business layer isn't dependant on the infrastructure layer. I much prefer the onion over the traditional 3-layer model. But I still believe it is fully feasible to use a 3-layered architecture if you don't believe in exchanging e.g. your ORM: see this link for why: ayende.com/Blog/archive/2010/07/30/…Amalgamation
Using an IoC container is a trade-off as it introduces complexity for looser coupling. It's all about what you need. EDIT: And you can still use interfaces and dependency-injection between your layers in a 3-layer architecture to facilitate testing.Amalgamation
I am starting to understand where you're coming from... if you edit your answer, I can switch my vote.Marielamariele
R
2

Read "Fundamentals of Software Architecture: An Engineering Approach", Chapter 8, Page 100 to 107.

The top-level partitioning is of particular interest to architects because it defines the fundamental architecture style and way of partitioning code. It is one of the first decisions an architect must make. These two styles (DDD & Layered) represent different ways to top-level partition the architecture. So, you are not comparing apples and oranges here.

Architects using technical partitioning organize the components of the system by technical capabilities: presentation, business rules, persistence, and so on.

Domain partitioning, inspired by the Eric Evan book Domain-Driven Design, which is a modeling technique for decomposing complex software systems. In DDD, the architect identifies domains or workflows independent and decoupled from each other.

The domain partitioning (DDD) may use a persistence library and have a separate layer for business rules, but the top-level partitioning revolves around domains. Each component in the domain partitioning may have subcomponents, including layers, but the top-level partitioning focuses on domains, which better reflects the kinds of changes that most often occur on projects.

So you can implement layers on each component of DDD (your friend is doing the opposite, which is interesting and we might try that out as well).

However, please note that ("Fundamentals of Software Architecture: An Engineering Approach", Page 135)

The layered architecture is a technically partitioned architecture (as opposed to a domain-partitioned architecture). Groups of components, rather than being grouped by domain (such as customer), are grouped by their technical role in the architecture (such as presentation or business). As a result, any particular business domain is spread throughout all of the layers of the architecture. For example, the domain of “customer” is contained in the presentation layer, business layer, rules layer, services layer, and database layer, making it difficult to apply changes to that domain. As a result, a domain-driven design approach does not work as well with the layered architecture style.

Everything in architecture is a trade-off, which is why the famous answer to every architecture question in the universe is “it depends.” Being said that, the disadvantage with your friend's approach is, it has higher coupling at the data level. Moreover, it will creates difficulties in untangling the data relationships if the architects later want to migrate this architecture to a distributed system (ex. microservices).

Roughage answered 22/9, 2022 at 13:25 Comment(0)
F
0

N Tier or in this case 3-tier architecture is working great with unit tests . All you have to do is IoC (inversion of control) using dependency injection and repository pattern .

The business layer can validate , and prepare the returned data for the presentation \ web api layer by returning the exact data which is required . You can then use mock in you unit tests all the way through the layers. All your business logic and needs can be on bl layer . And Dal layer will contain repositories injected from higher level.

Foment answered 6/5, 2021 at 21:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.