How to organize 'use case' code?

How to organize 'use case' code?

Old forum URL: forums.lhotka.net/forums/t/6822.aspx


sidwall posted on Monday, April 20, 2009

Hi,

I'm trying to figure out a good solution on how to organize user case code. Say you have a Car and a Map object. You also have a use case that says that a user should be able to drive to the nearest building. The method that does this could look like:

Point point = myMap.FindNearestBuilding(myCoordinates);
myCar.DriveTo(point);

The question is where to put this method. I've been trying two different solutions:

1. Put the method in the main business object (i.e. the car).

class Car
{
  public void DriveToNearestBuilding(Map myMap)
  {
    Point point = myMap.FindNearestBuilding(this.Location);
    DriveTo(point);
  }

  private void DriveTo(Point point)
  {
    //DoStuff
  }
}

2. Put the method in a facade class.

class MyFacade
{
  public static void DriveToNearestBuilding(Car myCar, Map myMap)
  {
    Point point = myMap.FindNearestBuilding(this.Location);
    myCar.DriveTo(point);
  }
}

The disadvantage with 1 is that the car object get a lot of dependencies to other business objects (that are not children).

The disadvantage with 2 is that is not pure object oriented.

Also the example above is an extremely simple one. Most often there are many business objects involved in solving a use case. Does anyone have a magic bullet for this kind of problem?

Regards,
Anders Sidwall

ajj3085 replied on Monday, April 20, 2009

What's not OO about the facade?

sidwall replied on Monday, April 20, 2009

Well as I see it there should be a domain object (aka business object) that is responsible for the task (use case). In the example it is the Car class that is mainly responsible for the task. The facade object is not a domain object it's just a container of use case code.

The main issue I think is that it should be easy to use the business objects.
When I develop the client that uses these objects I want to know if I should use facade classes or the business objects directly.

a. If we go all the way and say that we should always use faced classes then the facade classes will be filled with a lot of methods that simple call one method in a business object to achive the task.
 A lot of unnecessary code as I see it.

b. If we go only half way and say that we should only use facade classes for methods that actually coordinate many business object to perform a task then the client developer will not know if he should look for methods in business objects or in the facade classes.

c. If we don't use facade classes we get a lot of dependencies between the business objects.

No matter the alternative I don't like the outcome.

 

JoeFallon1 replied on Monday, April 20, 2009

I use Option b extensively and am quite happy with it. I originally called it a Unit of Work but later switched to the term Use Case Controller. (Although I still suffix the BO name with UOW out of habit.)

A USe Case Controller BO is simply a CSLA root object that is instantiated through DataPortal.Create and any praameters it needs to fetch other BOs that it will contain. (Like someKey As Integer).

The Controller BO co-ordinates the other BOs and can rules that evaluate either at its own level or across BOs. It can also act as the start point of a Transaction where you can Save many contained BOs in a single tr.

This model keeps the contained BOs "pure". They only do what they are supposed to do. That way the contained BOs can be re-used in other Use Cases without fear that they will cnotain "useless" methods for that other case.

YMMV
Joe

sidwall replied on Monday, April 20, 2009

Thanks for the interesting reply. I have a couple of questions:

1. Do you have 1 controller that you put all use cases in or do you have several?

2. How do the client-side developer know if he should look for methods in BOs or in the controller class(es)? Do you document when to use the Controller and when to use BOs directly or do you solve the problem in another way?

Regards,
Anders

JoeFallon1 replied on Tuesday, April 21, 2009

sidwall:

1. Do you have 1 controller that you put all use cases in or do you have several?



Regards,
Anders



I have several.
One for each use case.
You can consider a UI screen to be a use case.
In that example you need to determine which other BOs will be required for that screen and have your controller BO fetch them too. You may need a few dropdowns or a parent-child grid or ....

Joe

ajj3085 replied on Monday, April 20, 2009

Sure it's a domain object. It's responsiblity to to make the car drive to the nearest building. It's perfectly valid that one class use others to perform it's task.

I don't think you need to go all the way and say "it must be done this time every time." Your concerns about the developer should be tackled by training your client developer on proper use of the API.

Whether or not you need the facade should be decided by how often the "drive to nearest building" command can be executed in your UI code. If there is only one place in the UI that can do this, I'd just have it do the lifting (finding the building, then telling the car to drive to it).

sidwall replied on Monday, April 20, 2009

Thanks for the feedback.

The more I think about it the more I prefer alternative b which is what you suggest (if I interpret your answer correctly).

I guess there is no way around that we have to document how the API should be used.

Regards,
Anders

Copyright (c) Marimer LLC