3

So far I put functions into objects, if those functions work exclusively on the object's variables/state. Basically I'm following a non-anemic/rich domain model approach.

However, it becomes more difficult, if the behavior is only partially based on the object's state. In those cases I see two options:

  • Non-anemic approach: pass the additional information as argument to the object

obj.doSomeCalculationsAndSetAValue(someAdditionalInformation)
  • Anemic approach: Create a "service object" that lives on top of the domain object. The service object has all the information it needs, namely the domain object itself and the "additional information".

class ServiceObject{
    AdditionalInformationWrapper additionalInfos;

    //uses additionalInfos and gets information from domain object to do calculations;
    //use obj-setter to set the calculated value
    public void doSomeCalculationsAndSetAValue(DomainObject obj);
}

When should I keep the logic inside the domain object and when inside the service object?
Is there another alternative?

2 Answers 2

2

The first thing to think about is who is responsible for the doing? The answer to that question really boils down to whether it is reasonable for someone else on the team to expect the method to belong as part of the domain object. If you can't make a good argument for the method to belong to either domain object, then you might be looking at a service object.

However, something that might be worth considering is whether the SetAValue should be part of the service object... Setting values is the responsibility of the domain object, doing calculations can very well be part of your service object. Also, you may consider a bit of a rearrangement:

class ServiceObject {
    public CalculationResult doSomeCalculation(allArgsNeeded);
}

and invoking it like this:

obj.processCalculation(serviceObject, argsNeeded);

inside your domain object it would work like this:

public void processCalculation(serviceObject, argsNeeded) {
    result = serviceObject.doSomeCalculation(allArgsNeeded);

    // do something with the result
    setAValue = fromResult;
}

Separating the calculation and the setting can help keep a rich domain object while still supporting service objects. Just provide all needed arguments to the method instead of hiding an argument as a class attribute for your service object.

1

I think you could write the code either way equally elegantly.

I make the choice between ADM and OOP depending on how I use the object.

For long lived apps where multiple operations will be performed on the same object it makes sense to keep that instance in memory and call Object.DoWhatever(), Object.NowDoThis() etc.

However, when the object is temporal, ie instantiated in a web call, a single operation performed and then disposed of It makes more sense to keep the service around in memory, and reuse it for multiple objects.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.