3

Unbeknownst to me while I was building it, I built a "pyramid" architecture. I did not realize this until I laid it out in my new Visual Studio 2013 Layer Diagrammer. Each layer depends on the layer below, and all the other layers below that.

I suspect this is the cause of some of my woes. Each higher layer violates the SRP, because it has more than one reason to change, right? It has multiple contracts with multiple foundational layers. If any of those layers changes, the component has to change.

My question is, how can I refactor this? It's 19,000 lines of code but I can refactor it given enough time as long as I have a solid refactoring strategy.

And as a side note, I also invite your speculation as to why I felt the need to create it like this in the first place. Is this an anti-pattern? Does it have a name?

enter image description here

EDIT

I christen this anti-pattern "The Garlic Architecture"

toddmo
  • 533
  • 4
  • 11
  • [How do you find your way in deeply nested, interfacey code?](http://programmers.stackexchange.com/questions/105018/how-do-you-find-your-way-in-deeply-nested-interfacey-code) – gnat Mar 06 '15 at 17:43
  • While 19 KLOC isn't trivial, at least it isn't 500 KLOC. – Dan Pichelman Mar 06 '15 at 18:15
  • 2
    SRP is for classes, not for layers. – Doc Brown Mar 06 '15 at 18:20
  • @DanPichelman, yeah no kidding. Better to refactor earlier than later. I literally have done this on four projects now and stall out at about 15k lines each time, and never had an inkling why, until now. – toddmo Mar 06 '15 at 18:21
  • @DocBrown, Hi Doc, good to see you again. What's wrong with this picture? Does it strike you in any way? – toddmo Mar 06 '15 at 18:22
  • If the middle layers do nothing but redirect method calls to the next layer, then get rid of them. – MatthewMartin Mar 06 '15 at 19:05
  • @MatthewMartin, Thanks. What each layer does, is aggregate, inherit or use stuff in the layers below it. So if I'm in any class, and I need something I don't have, I have just added it to the "appropriate" layer. The gist of my woes is that there are actually multiple pyramids; reporting is not the only thing floating above all these other levels. So if I "fix" something to make reporting work better, I may break something else that depended on what I "fixed". I'm trying to learn TDD but I suspect this architecture is flawed. – toddmo Mar 06 '15 at 19:28
  • It looks like [Onion Architecture](http://jeffreypalermo.com/blog/the-onion-architecture-part-1/) in reverse. – Robert Harvey Mar 06 '15 at 19:43
  • Does this code base use an dependency inversion patters? (dependency injection in constructors for example?) – MatthewMartin Mar 06 '15 at 20:37
  • @MatthewMartin, no, it does not. I need to do that. I wish my boss could give me a month with no help desk tickets so I could implement that. I'm trying to figure out how to introduce that incrementally, if that's even possible. – toddmo Mar 06 '15 at 20:58
  • @RobertHarvey, please answer, so I can mark as answer and you can receive your points. I need to (almost) completely invert my dependencies. The article puts me in a much better direction. – toddmo Mar 06 '15 at 21:00
  • @DocBrown SRP works for methods, classes, layers, and automobiles. It's why cars-boats never caught on. :P Also, A layer should only communicate with what's directly above and what's directly below or it isn't really a layer at all. – candied_orange Mar 07 '15 at 08:27
  • @CandiedOrange: I am not interested in starting a flame war on this, but there is more than one perfectly valid opinion about what a layered architecture might be, and which communication is allowed. And the OP was clearly talking about the SRP in the sense defined by Bob Martin (http://en.wikipedia.org/wiki/Single_responsibility_principle), which is for classes, not for layers. Layers are typically for separation of concerns, which is a much weaker constraint than the SRP. – Doc Brown Mar 07 '15 at 23:16
  • @DocBrown SoC and the SRP are both about designing abstractions. They are two halves of the same coin. Doing one means doing the other. They are as different and the same as fractions and percentages. A class is a particular kind of abstraction. So is a layer. SoC says separate your things. SRP says your thing should do one thing. I’m saying that’s the same thing. The constraint isn’t against what a thing can be made of (even an int has many bits). It’s against what a thing can be for. So at any level the constraint is the same. But maybe that's just my opinion. – candied_orange Mar 08 '15 at 03:18

1 Answers1

5

Based on the picture you provided, this looks like Onion Architecture, but with the dependencies proceeding in reverse.

A typical onion architecture looks something like this:

enter image description here

Each layer presents interfaces (an API) to the layer above it, and communicates with the layer above it, and the layer below it. The onion model has some similarities to a Model-View-Controller architecture or a three-tier architecture, though note the inclusion of a Tests layer, an Infrastructure layer, and an "Inverter." The Domain Model communicates with a database (normally shown as a component external to this diagram).

The consultant from whom I borrowed this picture describes it like this:

For web-based enterprise applications, we espouse the benefits of a specialized hexagonal architecture known as Onion Architecture. The core principle of this architecture is to build the application around an independent object model that describes the business domain. Component coupling is unidirectional toward the center with separation between component contracts (interfaces) and implementations.

Understanding the structure of the architecture is simple. In practice, the architecture relies on the Dependency Inversion (DI) principle to assemble the components at runtime. We isolate the "Inverter" into a separate physical tier to avoid leaking responsibilities.

Robert Harvey
  • 198,589
  • 55
  • 464
  • 673