How to separata application specific / agnostic business rules?

436 views
Skip to first unread message

Georgef

unread,
Nov 6, 2013, 3:50:47 PM11/6/13
to clean-code...@googlegroups.com
In a couple of presentation videos Uncle Bob talks about application specific and application independent business rules and that these two should be separated.

My question is how do we know which is which when designing the application? For example if I have a User entity, which is an independent business rule, because it could be reused in other applications, but then again that entity should also have an ID of some kind which is application specific...

Łukasz Duda

unread,
Nov 6, 2013, 5:56:36 PM11/6/13
to clean-code...@googlegroups.com
In my opinion entities contain application independent business rules, while interactors impose application specific rules. For example User entity can validate unique name, constraint which applies for each application, but password complexity validation performed by interactor can be different depending on application.

Georgef

unread,
Nov 7, 2013, 3:00:25 AM11/7/13
to clean-code...@googlegroups.com
You mean by inheriting the app. independent entity and adding app. specific functionality to it?

Łukasz Duda

unread,
Nov 7, 2013, 4:55:04 AM11/7/13
to clean-code...@googlegroups.com
By an interactor I mean an object implementing a specific use case. It manipulates entities rather than inherits from them.

// entity example
package example;

import java.util.Date;

public abstract class User {
    private long id;
    private String name;
    private String password;
    private Date registrationDate;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getPassword() {
        return password;
    }

    public String getCode() {
        // application independent rule ----->
        return registrationDate.getTime() + name;
    }

    public Date getRegistrationDate() {
        return registrationDate;
    }

    public void setRegistrationDate(Date registrationDate) {
        this.registrationDate = registrationDate;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

// interactor example
package example;

public class SetPasswordCommand {
    private UserGateway userGateway;
    private PasswordValidator passwordValidator;

    public SetPasswordCommand(UserGateway userGateway) {
        this.userGateway = userGateway;
    }

    public void execute(SetPasswordRequest request) {
        User user = userGateway.get(request.getUserId());

        String newPassword = request.getPassword();

        // application specific rule
        if (passwordValidator.isValid(newPassword)) {
            user.setPassword(request.getPassword());
            userGateway.save(user);
        }

        //...
    }
}

Georgef

unread,
Nov 7, 2013, 10:58:56 AM11/7/13
to clean-code...@googlegroups.com
I'm strictly talking about the entities. From your perspective an entity is a data structure which contains app. independent business rules ONLY, right?
And you're saying that the app. specific business rules are implemented in the interactor?

I guess I'm confusing what to put into the entities, because my development process is currently limited to that specific application. Is this a refactoring process also, that later on, you extract app. agnostic business rules for use in another application?

I'm having a hard time designing this stuff upfront...

Uncle Bob

unread,
Nov 7, 2013, 12:01:09 PM11/7/13
to clean-code...@googlegroups.com
This is why making reusable frameworks is so hard.  It's hard to know what is reusable (application independent) and what is not reusable (application specific).  The best strategy is to make a guess, and then evolve the design if and when it is proven incorrect.  

So, for example, if you are building a single application, you make the best guess you can about the entities and their data.  Later, when more applications are written, you'll likely have to refactor those entities a bit.  

Don't worry about getting it right up front.  You'll have lots of opportunities to improve the design later.  

Roberto Guerra

unread,
Nov 7, 2013, 12:30:28 PM11/7/13
to clean-code...@googlegroups.com
I used to be paralyzed by analysis. I spent more time thinking how to design the application and make it modular. But I never produced anything because I never got the perfect design in my head. Now I just start writing the app and as soon as it starts to feel messy, I refactor. Some information wont be available until you start actually writing the app. This means that I also have to constantly refactor, but it is much easier to refactor in small increments than trying to get it right from the beginning.

Łukasz Duda

unread,
Nov 7, 2013, 4:05:50 PM11/7/13
to clean-code...@googlegroups.com
I don't know If I make it right, but personally I put most of reusable business logic in kind of utility interactors used by other interactors. These utility interactors go then to the next application.
My entities look as common data structures. I move to isolated packages these entities, which aren't related to specific customer. If I need to add something customer dependent, I extend them in another package.
I decide what to make reusable, after deploying a few applications. Some parts repeat in each of them and I try to make them as easy to use as possible for another application.

Andreas Schaefer

unread,
Nov 13, 2013, 5:43:53 PM11/13/13
to clean-code...@googlegroups.com
I'd rather avoid anemic entities (plain data structures without behaviour) and instead over time as knowledge about what is enterprize wide (aka app independent) grows, put reusable functionality into the entities itself. thus you avoid the additionally needed packages .. and it makes it more obvious, more explicit in what scope a specific functionality is in (app or enterprize domain). the more intuitive, the simpler it is to recognize that, the better it is for the team maintaining the code base.

the one thing that I'd like to hear your thoughts on, is what approaches are you taking to avoid your entity classes are getting to big over time.
do you leverage partial classes e.g. to encapsulate validation business rules?

Roberto Guerra

unread,
Nov 15, 2013, 12:07:58 AM11/15/13
to clean-code...@googlegroups.com
I think the term anemic domains/entities get a bad rap. There are times when all you ever need is a an anemic entity. Like most engineering rules, they are just guides that we should know when they apply. Most rails (and grails) developers fall in this trap, and dump a pile of logic in their models/domains because they read that article on rich/anemic domains, but never understood the concepts of domains and entities, and conflate their meanings. There are some entities that are fine being anemic if the business logic dictates that they are.

Łukasz Duda

unread,
Nov 15, 2013, 6:55:08 AM11/15/13
to clean-code...@googlegroups.com
Most of my business rules including validation goes into utility use cases. The root cause of my simple entities can be requirements, which are different for every customer. Therefore currently I prefer more flexible interactors, which aren't as stable as entities.

Łukasz Duda

unread,
Nov 15, 2013, 7:16:41 AM11/15/13
to clean-code...@googlegroups.com
I pass utility interactors as dependencies to another, so the responsibility is divided, and each interactor is about 150-300 lines long. Unfortunately tests are longer (max. about 450 lines), but I didn't find out yet how to organise them different way.
Instead of using partial classes I try to extract responsibilities to another classes.
As you already noticed my entities are rather anemic, so they aren't big. I tried to find rules common for different applications, but usually they need some flexibility and doesn't fit into entities.


W dniu środa, 13 listopada 2013 23:43:53 UTC+1 użytkownik Andreas Schaefer napisał:

Roberto Guerra

unread,
Nov 15, 2013, 10:33:31 AM11/15/13
to clean-code...@googlegroups.com
This is an example, I believe, of a good design. http://oredev.org/2013/wed-fri-conference/entity-framework-in-core-business-applications-that-leverage-ddd . Granted, it is focused on .Net and the Entity Framework, but the general concepts apply in any environment.

Andreas Schaefer

unread,
Nov 15, 2013, 2:23:43 PM11/15/13
to clean-code...@googlegroups.com
Łukasz, then you're doing it absolutely right, at least concerning the business rules that vary by each app/customer. but if the business rules really are reusable across apps/customers, then imo I'd put them into the entities instead more interactors.
one example that comes to my mind is to validate the value type "dateRange" (which itself is an entity, but without unique identifier). why would one ever not want to validate that dateTo is greater than or equal to dateFrom!?
but of course what really matters is that you do encapsulate the reusable code. how one does it design and implementationwise might be considered as technical detail.
others furthermore differentiate between app<->enterprize and default<->customized functionality. the latter implemented by hooks/userExits in the code.


just to throw it in, greg young said in a talk about DDD/CQRS: (asuming the competitive advantage justifies the design effort) depending on the apps context, you'd probably have individual/separate domain models anyway.
but maybe this goes to far here. just wanted to say that there are so many variables and different customer needs, that you can't tell a "one fits all" design. as always: it depends ;)
Reply all
Reply to author
Forward
0 new messages