Mark Needham

Thoughts on Software Development

Coding: Packaging by vertical slice

with 30 comments

On most of the applications I’ve worked on we’ve tended to organise/package classes by the function that they have or the layer that they fit in.

A typical package structure might therefore end up looking like this:

  • com.awesome.project
    • common
      • StringUtils
    • controllers
      • LocationController
      • PricingController
    • domain
      • Address
      • Cost
      • CostFactory
      • Location
      • Price
    • repositories
      • LocationRepository
      • PriceRepository
    • services
      • LocationService

This works reasonably well and allows you to find code which is similar in function but I find that more often than not a lot of the code that lives immediately around where you currently are isn’t actually relevant at the time.

On the last couple of applications that I’ve worked on we’ve been trying to group code around a domain concept or vertical slice of functionality.

Therefore instead of the above code we’d end up with something more like this:

  • com.awesome.project
    • location
      • Address
      • Location
      • LocationController
      • LocationRepository
      • LocationService
    • platform
      • StringUtils
    • price
      • Cost
      • CostFactory
      • Distance
      • Price
      • PriceController
      • PriceRepository

We were having a discussion about grouping code like this last week and I was struggling to describe what I prefer about the latter approach.

In the code base that I’m currently working on, which provides an API for other systems to do stuff with, it seems to lead to a design where we have created lots of potential micro services which could be deployed separately if we wanted.

That possibility wasn’t as clear to me until we started grouping code this way.

Another cool thing is that it’s made us think about the domain of the code more and whether the grouping of classes actually makes sense. We can also see which classes fall inside an aggregate root.

In the above example under ‘pricing’ we can tell that Price is an aggregate root because it has a repository which allows us to get one and we can also tell that Cost is probably contained by Price since we don’t have a way of directly getting a Cost.

We stop thinking about the domain classes as a whole, instead we think about them in their groups and how their aggregate roots might interact with each other if at all.

One disadvantage of grouping code like this is that if we’re writing a new repository, for example, we’ve got further to navigate to find another one to base ours on.

On the other hand you could argue that if we’re doing that then perhaps there’s an abstraction we can pull out to remove the problem.

It’s an interesting approach to grouping code and one thing we’ve started noticing is that we end up with some packages which have a lot of classes in them and others which have very few.

We’re not sure whether this is a symptom of us not breaking down those particular packages enough or if there are just some areas of the domain that are bigger than others.

These are just some of my early observations so it’d be interesting to hear other’s thoughts on whether this is a good/bad idea.

Be Sociable, Share!

Written by Mark Needham

February 20th, 2012 at 9:54 pm

Posted in Coding

Tagged with

  • http://twitter.com/JakCharlton Jak Charlton

    It is the way I prefer to group code…

    It matches the vertical slices
    It matches the use cases
    It matches the user stories
    It matches the UL
    It matches task based UIs / service layers

  • Vishnu Iyengar

    wow, I really like this post :)

  • http://andypalmer.com/ Andy

    This is a good idea… I’ve been saying for ages that grouping things by pattern names is a bad idea, and that I would prefer something closer to the domain.
    I’m still not 100% sold on this way, it still feels like there’s something missing; but I really like the idea of micro-services.

    As a further step, I’d also look for ways to eliminate the pattern names from the classes (Repository, Controller)… 

  • Tom Akehurst

    I’ve been organising things this way since first seeing it in the e4.com codebase. 

    Having all the source files for a particular feature under a common root feels far more natural than them being distributed between layers, and possibly reduces the urge to make every class a stereotype by default.

    I also find you tend to end up with more numerous, smaller, and cohesive packages this way.

  • Kenji Hiranabe

    Interesting approach… Any thoughts about cyclic dependencies?

  • http://www.markhneedham.com/blog Mark Needham

    Hmmm haven’t actually come across that as yet. Will let you know when we do…did you have any specific example which might have a cyclic dependency? Might be easier to imagin what we could do…

  • Anonymous

    I agree with this model as well. Code that changes together is packaged together. A side effect of using this is that it makes it pretty easy to mine version control histories for areas of the system that change often and they can be easily identified by package names. This can give you some insights into test coverage, etc at a feature level versus file level.

  • http://twitter.com/twasink Robert Watkins

    I’ve come to prefer the vertical slice organisation as well. It’s an especially good fit if you’re building an application around a plugin architecture (e.g. OSGi) – each plugin has a root point to navigate from.

  • Cairey01

    Although I like this approach, the limitations come in when “price” has dependencies on stuff that specific for the controller. You don’t necessary want dependencies polluting your domain. Organising by behaviour is fine if it happens in its separation. So Price -> Price, Cost, Cost Factory

  • http://twitter.com/unclebobmartin Uncle Bob Martin

    Mark,  Needless to say I like the approach.  (See cleancoders.com episode 7.)  The next step is to decouple the controllers from the domain objects.  Traditionally Controllers (if we are talking about web systems) are coupled to both the interface, and the domain.  I like to split the domain portion of the controllers into interactors that understand how to communicate with the domain objects.  The controllers simply unpack the data from the interface and then pass the data to the interactors.

  • http://twitter.com/regularfry Alex Young

    Presumably there’s some shared code between LocationRepository and PriceRepository – or at least if there isn’t here, it’s not impossible that such a thing might happen on another project.  Where would you put that shared code?

  • Gerry Askefalk

    At my last position, Expert Systems AB, we had an organisation of code along the lines you are currently trying. My experience is that if felt very natural. We used AOP for som crosscutting concerns and had some separate ROOTs for systemwide functionality like HBM extensions etc.

  • http://twitter.com/tac188 Travis Calder

    I recently got my team to let go of the traditional Java deep-package pattern and try out the first structure in your post. I’m sure you can imagine, but so far it’s been far more effective.

    Just reading about it, I definitely like your second structure even more. Now that my team is open to the idea of change, we’ll have to give that a try. Thanks for the suggestion ^^

  • http://twitter.com/crazydaysorg Aaron Day

    Personally I like the latter option.  I cry every time I see an Android project that has all the Activities, Fragments, etc in their own package.  Breaking the project up into feature package trees makes much more sense.

    One drawback from this approach is when you have two branches of the package tree which at first are unrelated though a new feature requires aspects of both together.  Then determining who owns what among the shared classes can become difficult.

  • Anonymous

    Funny thing is, I started to travel around promoting this kind of package structure (and more generally thinking about how to use Java package as a dependency management artifact) recently. Have a look at the slide deck at slideshare.

    Here are the crucial parts that I think are superior to the traditional approach:

    1. The package scope actually gets useful again. Only types that actually need to be accessible by other slices need to be public. I tend to recommend having a separate package (or maybe even a separate Maven module) for web related stuff (as the web pulls in quite a few dependencies (Servlet API etc.) that all the other code shouldn’t or even must not have a dependency on. Thus the only types visible from the slice package are the service interface plus the domain types contained in its signature. Everything else is package protected. Actually, try ask developers if they already use the default scope in their apps and if not why they think it’s the default one in Java ;).

    2. Layering becomes an implementation detail. Actually it doesn’t matter if a slice really uses a layered architecture it could just be arbitrary components delegating calls to separate concerns. Using a repository is an instance of SEP applied. Beyond that layering is understood by almost every developer, so it’s not a big deal of getting a picture of what’s going on when looking into a package. Try that with layer packages.

  • David Atkins

    I’m completely sold on this approach. For me it greatly reduces the amount of jumping around packages required when working on a particular area of an application.

  • leif

    After reading Eric Evans Domain Driven Design we started with this kind of grouping. It looks like that:

    com.awesome.project
         component
                  brm
                       internal
                  label
                       internal
                  loanfile
                       internal
                  qualification
                       internal
                  …

    The problem is, that these “slices” are often to fine grained, so that you like to call internals of another “component”. Our latest move was to focus on extracting maven modules. This feels more natural and seems to be a better fit for a “component”. We create one module for the API and one implementation module. A teammate gives a related talk at the Berlin Expert Days (http://bed-con.org/talks/modularisierung-wagen-warum-es-sich-lohnt-diesen-weg-einzuschlagen-und-wie-man-unterwegs-uberlebt/). How to group code inside a module or vertical slice needs some more experimentation and more discussions. 

  • http://www.markhneedham.com/blog Mark Needham

    @1987021a0ad2bc4639d84cd52f2fe0c9:disqus With respect to Repository/Controller is it the responsibility of those classes that you think isn’t good or is it just that you prefer to give them a different name?
    I find the useful thing about having the pattern names in classes is that people tend to know what they mean and therefore have a couple of starting points even if they haven’t worked on the code base for very long.

    Would be interesting to hear how you’ve been writing the sort of code that deals with the incoming HTTP requests/saving to some sort of persistence.

  • http://twitter.com/mwjacks0n Matt Jackson

    Mark, this is exactly the approach I’ve been using in the last 6 months, for the exact reasons you’ve outlined. 

    Obviously there is a section of infrastructure (like IOC wiring, DB stuff, logging) that stretches horizontally across the codebase, but for all intents, vertical organisation makes the most sense to me.

  • http://www.markhneedham.com/blog Mark Needham

    @twitter-83657910:disqus with respect to the infrastructure stuff we’ve noticed that happening as well so we’ve made an exception to have a ‘platform’ package where that type of code can go.

    I guess if there’s code that’s common enough to be used by classes in different packages then that might also be a candidate to go into that package as well. Haven’t noticed that happen so far for anything but infrastructure type code yet though.

  • http://www.markhneedham.com/blog Mark Needham

    @olivergierke:disqus nice idea about only making what would effectively be the aggregate roots have a public modifier. Think I’ll have a look tomorrow and see whether we can do that or if we’ve been naughty and accessed classes that we shouldn’t be! 

    By the way, ‘SEP’ as in Single Entry Principle or does it stand for something else?

  • Oliver Gierke

    Sorry, SEP was meant to be the well known SRP (I just fixed it in the original comment). Working with Spring you can easily have all Spring bean implementations package protected anyway as Spring will still be able to instantiate those and clients can refer to them via their (public) interface. A very elegant way to prevent clients from accessing an implementation class directly.

    The example I usually give is a UserRepository simply storing users as well as a UserManagement service that cares about generating initial passwords and actually encrypting them. In a layer package approach you have to make the UserRepository interface public which opens the system up to someone just letting the container inject a UserRepository instance and access and save users without proper password handling. In a slice package approach you can evan have the UserRepository interface package protected and only expose user management functionality through the UserManagement service interface.

    Generally I think the less public types the easier a system can be understood as you need to dive into the internals only if you want to understand the internals. With layer packages there’s no natural distinction between internal and API parts of the codebase.

  • http://andypalmer.com Andy Palmer

    I think that having the pattern name in the name of the class limits our thinking. It’s probably not such an issue for Controller/Repository but could result in us not seeing a better solution for State/Strategy/Decorator etc.

    Pattern names also don’t tell us why a class is there, they tell us how it has been implemented (or at least, how it _was_ implemented)

    In ActiveRecord (IIRC), you can call People.all to get a list of Person. I like that better than PersonRepository.

    I’ll blog about this at some point, but I think that a pattern name is a metaphor that is understood by many programmers across many languages. By it’s generality, it doesn’t carry a lot of information. I prefer metaphors that are easily understood by the people on the project that carry a lot of information within that bounded domain.
    (for example, on one project we called our webservices clients “couriers”, the objects that created the requests were “clerks” and the acknowledgement that came back from the webservice was a “carbon copy”)

  • http://twitter.com/regularfry Alex Young

    Ah, I see from other responses that that’s what “platform” is for.

  • http://twitter.com/regularfry Alex Young

    Uncle Bob says “an architecture is a structure where you can draw lines separating parts where all the dependency arrows go the same way” (or words to that effect).  I think that’s a reasonable statement, and it implies that units with circular dependencies must sit within the same vertical slice.

  • Monstercorp

    With modern IDEs like IDEA or VS+Resharper, finding some code is not some hard. How to make reuse more effective would be my first priority. I don’t want to re-use a price calculation logic with a bundle of useless views.

  • Oliver Gierke

    Take the following example: we have Customers which have Accounts. A naïve way of modeling this would be to give the customer a list of Accounts as well as the Account a property of type Customer. This cyclic dependency makes it one slice effectively. However, you might consider the customer slice “more core” than the accounts functionality as we theoretically can perfectly have a system only managing customers (a CRM of some kind). So I’d go ahead and remove the Account dependency in the Customer class and instead provide a List findByCustomer(Customer customer) on the AccountRepository. This way the accounts slice has a dependency on the customer one which is perfectly fine.

    Bottom line is: in general a cyclic dependency implies the participants to actually form one slice. There’s various techniques how you can split up them to make it a directed dependency instead.

  • http://davidsantoro.net David Santoro

    Packages, Namespaces, Projects are not tool that should be used to help you “Find” code. They should be tool to identify larger part of a systems, parts that maybe in future will be split in completely different applications. They are useful tools to help you reduce dependencies between areas of you application. 
     

  • Oliver Gierke

    But if code is not easy to find it means low cohesion. With low cohesion how do you expect a system to be easily decomposable into modules? I think the latter approach (which leads to easy to find code) actually leads to more natural cohesion and thus makes it much easier to reduce dependencies as you can use the package scope (in Java) to avoid someone creating dependencies on internals and thus ease dependency management inside a module.

  • Dave Cameron

    Sadly, Rails depends on the first kind of organization. I consistently get lost in Rails code bases because of that.