1

I've recently read that calling classes **Manager* is a bad thing due to their not exact name and a possibility that they might become god objects. However, is it a good practice to provide 'Manager' as a wrapper for multiple different methods from different classes dealing with the same business object?

Let's say my callers want to interact with orders. Is it better to mix all kinds of methods into a single **Manager* class which will only delegate them to a proper class or let the caller use the proper class itself.

So

OrderManager orderManager = new OrderManager();
orderManager.cancelOrder(order); -> delegates to OrderShredder
orderManager.sendOrder(order, destination); -> delegates to OrderSender

or

new OrderShredder().cancelOrder(order);
new OrderSender().sendOrder(order, destination);

And what about classes which do a bit more than a simple delegation (they use multiple delegations, execute them in a correct order or choose a next path based on some result from a delegate). Can these type of methods (like below) be in some kind of a manager class?

public Order makeOrder(List<Product> products, Customer customer) {
    BigDecimal orderValue = this.productPriceCalculator.calculatePrice(products, customer);
    Order order = this.orderCreator.createOrder(products, customer, orderValue);
    boolean orderIsOk = this.orderValidator.validate(order);
    if (orderIsOk) {
        OrderStatistics orderStatistics = this.orderEvaluator.evaluate(order);
        boolean orderValueIsBigEnough = orderStatistics.isValueBigEnough();
        if (orderValueIsBigEnough) {
            this.orderSender.sendInformationAboutOrderSomewhere(order, orderStatistics);
        }
    }
    else {
        throw OrderNotOkException(order);
    }

    return order;
}

public void cancelOrders(Customer customer) {
    List<Order> customerOrders = this.ordersStorage.getOrders(customer);
    for (Order order : customerOrders) {
        orderShredder.cancelOrder(order);
    }
}
Bhargav Rao
  • 41,091
  • 27
  • 112
  • 129
Swato
  • 966
  • 2
  • 9
  • 13
  • "I've recently read that calling classes *Manager is a bad thing" - Do you have a link? – assylias May 10 '12 at 13:49
  • 2
    First half of [this article](http://www.bright-green.com/blog/2003_02_25/naming_java_classes_without_a.html) or a StackOverflow question [here](http://stackoverflow.com/questions/1866794/naming-classes-how-to-avoid-calling-everything-a-whatevermanager) – Swato May 10 '12 at 14:03
  • 1
    The name Manager is too vague, 'Service' is the preferred term. There is a good discussion of services in Evans' book *Domain-Driven Design*. – Nathan Hughes May 10 '12 at 15:48
  • 1
    I don't know, OrderManager and OrderService appear to me quite equally in terms of their vagueness. :) – Swato May 12 '12 at 14:01

1 Answers1

0

Why do you think you need to put business logic not into the business logic objects?

new OrderShredder().cancelOrder(order);

How about

order.cancel()

and actually do not care if this call itself calls into the OrderShredder (if you really need this)? This is a command to the object, you tell it things to do. How it does things, you don't care.

Run through the methods on the service/manager/whatever classes and have a look at the first argument's static type. Try to eliminate those classes by making the business logic object aware of themselves by actually assigning them behaviour.

For the naming side of things: There has been a very nice article about weasel words (unfortunately not free, german language) applying linguistics to naming questions. I can't remember the exact details, but the argument was that substantives ending with -er or -or are nominalized verbs and one should generally try to get rid of those, not just of the Manag-er.

Stefan Hanke
  • 3,258
  • 2
  • 28
  • 32
  • From a testability perspective constructing such an advanced object will be imho quite hard (Order object will need to know too much about everything and you would have to provide lots of empty implementations for all those classes which are injected into a constructor and you're not interested in). There is a nice example of whether methods should belong to an object or a service: Does a postcard send itself or is there a postman who delivers it? Currently I prefer the latter approach. – Swato May 12 '12 at 13:53
  • @Swato Do you have a link to a discussion of the postcard example? -- I don't think `Order` needs quite that much context. I'm thinking about that `Order.cancel()` is delegated to the class composing `Order` instances (`Customer` or whatever): `OwningCustomer.cancel(this)`. The `Order.cancel()` method is strictly not needed, but code actually calling `cancel` will have to deal with only the `Order` instance. – Stefan Hanke May 12 '12 at 15:41