Limiting Parameters - oop

Probably going to get shot down for this, but I have an issue with my parameters.
Say I need to store a race (Which I do)
During planning, I realized I needed to store things like:
Terrain of the race
location of the race
time the race starts
time admission ends.
Name of the Race
Types of member permitted to join
etc
In short, it's a ton of underivable data that can't really come from elsewere
and all in all, I have like, 22 parrameters for my JuniorRace object, and like 26 Parameters for my SeniorRace object, I've already coded it but it's messy and I don't like my work.
This wouldn't be a massive problem, and it actually won't be a problem AT ALL for the users since they won't see the business model, just the view model, but it is for me having to constantly comment these same parameters multiple times.
What is the best way I can stop using so many parameters every time I make a constructor, and every time I create a new object instance?
do I just try to use less and store data elsewhere, if so, where?
use more classes like Person would have Address and Details?
I'm really stumped here, will post my code, but yeah, it's a ton of parameters pretty much everywhere -- I'm not a very experienced OO programmer.

You could store all the parameters as a map and just pass in the map, something like:
Map myParams = new HashMap<String,Object>();
myParams.add("Terrain","terrible");
myParams.add("Location","Bobs back yard");
myParams.add("Length (yards)", 100);
myParams.add("Hazards", new String[] {"Bob's cat","The old tire","the fence"});
Then you could calll your routine like this:
SaveRaceCourse(myParams);
Maps and suchlike are great for passing around data.

As I can't see all 22 parameters this is a guess but most probably a correct one.
Are some of those 22 parameter related. If so group the related ones in another class and make SeniorRace a composition of all these classes.
For example: location and terrain seem related, admission period and allowed member types seems related to admission (maybe a fee is part of it too).
This way you will end up with a limited set of objects to pass, all related info lives together and evolve together.

Break it down by encapsulating similar properties in objects. It's called decomposition.
For example, your Race can accept a TimeCard encapsulating all the timing details, a Location which has the terrain and what not (maybe directions), an object encapsulating the requirements, ect...
class RaceTimeCard {
private final Timestamp admissionStart;
private final Timestamp admissionEnd;
private final Timestamp raceStart;
private Timestamp raceEnd;
public RaceTimeCard(Timestamp admissionStart, Timestamp admissionEnd, Timestamp raceStart) {
//init final fields
}
public void endRace() {
//clock the time that the race ended
}
}
class RaceLocation {
private final Terrain terrain;
private final Directions directions;
private final GPSCoordinates coordinates;
public RaceLocation(Terrain terrain, Directions directions, GPSCoordinates coordinates) {
//init final fields
}
}
class Race {
private RaceTimeCard timeCard;
private RaceLocation location;
public Race(RaceTimeCard timeCard, RaceLocation) {
//init fields
}
}
If you'd like, you could subclass Location and TimeCard to create specific instances:
final class Mountains extends RaceLocation {
public Mountains() {
super(Terrain.ROCKY, new Directions(...), new GPSCoordinates(...));
}
}
final class EarlyBirdTimeCard extends RaceTimeCard {
public EarlyBirdTimeCard() {
//specify super constructor with params
}
}
Now instantiating your Race object is as simple as:
RaceTimeCard timeCard = new EarlyBirdTimeCard();
RaceLocation location = new Mountains();
...
Race race = new Race(timeCard, location, ...);
If it's still too long, you can probably decompose more. The way I see it, you could have a RaceDetails object containing all the (already decomposed) details, then pass that to Race. Make sure to profile your application, make sure the overhead from object creation doesn't get too bad.

Related

NullObject Pattern: How to handle fields?

Suppose we have Book class which contains year_published public field. If I want to implement NullObject design pattern, I will need to define NullBook class which behaves same as Book but does not do anything.
Question is, what should be the behavior of NullBook when it's fields are being assigned?
Book book = find_book(id_value); //this method returns a NullBook instance because it cannot find the book
book.year_published = 2016; //What should we do here?!
The first thing you should do is to make your properties private.
class NullBook {
private year_published;
// OR solution2 private year_published = null;
public setYearPublished(year_published) {
this.year_published = null;
// OR solution2 do nothing!
}
}
You can also define the field private in the parent class, so the children will have to implement the setter to acces the field
class Book {
private year_published;
public setYearPublished(year_published) {
this.year_published = year_published;
}
}
class NullBook extends Book {
public setYearPublished(year_published) {
parent::setYearPublished(null);
}
}
Why use getters and setters?
https://stackoverflow.com/a/1568230/2377164
Thing is: patterns are about balancing. Yes, it is in general good practice to not return null, but to having else to return; but well: what is returned should still make sense!
And to a certain degree, I don't see how having a "NullBook" really helps with the design of your application. Especially as you allow access to various internal fields. You exactly asked the correct question: what should be the published year, or author, or ... of such a "NullBook"?!
What happens for example when some piece of code does a "lookup" on books from different "sources"; and then tries to sort those books on the published year. You sure don't want your NullBook to ever be part of such data.
Thus I fail to see the value in having this class, to the contrary: I see it creating a potential for "interesting" bugs; thus my answer is: step back and re-consider if you really need that class.
There are alternatives to null-replacing objects: maybe your language allows for Optionals; or, you rework those methods that could return null ... to return a collection/array of books; and in doubt: that list/array is simply empty.
Long story short: allowing other classes direct access to private fields is a much more of an import design smell; so you shouldn't be too focused on NullObjects, while giving up on such essential things as Information Hiding so easily on the other hand.

How to determine which class should have a specified method

This is a question regarding the concept of OOP.
Let's say I'm creating a game and I have a few objects:
Field - representig some field on the map.
User - representing a player.
Item - representing an item that user can have (for example shovel)
Now I know that player can dig a field using shovel. And this action will be a method of one of those classes. Is there some rule to determine which of those classes should have this method.
The most obvious performer of this action is the player (User), so User class could have method like digField(Field field). But actually the field itself is most affected by this action, so maybe it shold be the Field class method, like dig(User performer) or dig(Item toolUsed). Or maybe the Item itself should have a child class like Tool with a method like digField(Field field).
There are lots of ways to solve this problem and I was just wondering if there is some kind of simple best practice there.
Like said in other answers, it depends on what else is happening (or can happen in the future).
For example, for digging there can be some options:
user.digField(field, tool): this way can be helpful when your user also needs to spend time, or maybe he gets tired, i.e. use this way if you want to FOCUS on the user.
field.dig(user, tool): this way can be helpful when the field itself should be focussed on, like setting the status of the field.
tool.dig(user, field): this way can be used to change e.g. the status of the tool, or the maintenance needed.
However, in most cases there are a multiple of statuses/changes need to be set. So maybe it is best to create a separate class Action like:
public class Action
{
public void DigField(User user, Location location, Tool tool)
{
user.Status = Digging;
user.Energy -= 50;
location.Status = Digging;
tool.Status = Digging;
tool.Usage++;
}
}
As you can see this function may grow as action might get more complex. So what is a good way to call separate functions in the appropriate classes, like a mix:
public class Action
{
public void DigField(User user, Location location, Tool tool)
{
user.DigField();
location.Dig();
tool.Dig();
}
}
public class User
{
public void DigField()
{
Status = Digging;
Energy -= 50;
}
}
public class Field
{
public void Dig()
{
Status = Digging;
}
}
public class Tool
{
public void Dig()
{
Status = Digging;
Usage++;
}
}
This has the advantage to keep the functionality where it belongs.
Nothing prevents you from passing parameters, like if the energy drain for auser depends on the type of field, use:
public class User
{
public void DigField(Field field)
{
Status = Digging;
Energy -= field.Type == Clay ? 30 : 20;
}
}
It depends on the rest of your game. You can't architect your classes without thinking about all of it. So questions such as:
Are there many tools, do they perform different actions on different objects?
Are there many types of land masses (field, stream, etc)
Does the user have any effect (such as with strength) on the action
These types of questions are useful to think about before laying out your classes. As an example, if you have many different tools, then you could tie the digging with the shovel, which will detail what it does to different types of land (and which ones it can work with). Then maybe there is a tractor, which does something different to the land.
One last thought, the closer your classes match the real world, the better the classes work as the code expands. In other words, if you were describing a shovel to someone who has never seen one, your class should model itself after that kind of description.
This not a case of overloading, I think you have recognise the complexity but you are trying to escape it. It's been you take time to model it now,it may be costly later.
Here is what I think:
User object performs the action so it must have the User.Dig() method. Maybe you can decide to pass in an Item object (eg Shovel).
Field object reacts to the action (Dig) of the User object. You now have to determine what this reaction is. Also you determine what the action is.
Like you said there are likely many approach and I think game engines have solved problems like this but I don't use them so I can't recommend. If I would have to model what explain I first try out Observable Pattern https://en.wikipedia.org/wiki/Observer_pattern?wprov=sfla1
Good luck

How to structure object: OOP, composition

I have an object, let's call it a Request, that has associations to several other objects like:
Employee submitter;
Employee subjectsManager;
Employee pointOfContact;
And several value properties like strings, dates, and enums.
Now, I also need to keep track of another object, the subject, but this can be one of 3 different types of people. For simplicity let's just talk about 2 types: Employee and Consultant. Their data comes from different repositories and they have different sets of fields, some overlapping. So say an employee has a
String employeeName;
String employeeId;
String socialSecurityNumber;
Whereas a consultant has
String consultantName;
String socialSecurityNumber;
String phoneNumber;
One terrible idea is that the Request has both a Consultant and an Employee, and setSubject(Consultant) assigns one, setSubject(Employee) assigns the other. This sounds awful. One of my primary goals is to avoid "if the subject is this type then do this..." logic.
My thought is that perhaps an EmployeeRequest and a ConsultantRequest should extend Request, but I'm not sure how, say, setSubject would work. I would want it to be an abstract method in the base class but I don't know what the signature would be since I don't know what type the parameter would be.
So then it makes sense to go at it from an interface perspective. One important interface is that these Request objects will be passed to a single webservice that I don't own. I will have to map the object's fields in a somewhat complex manner that partially makes sense. For fields like name and SSN the mapping is straightforward, but many of the fields that don't line up across all types of people are dumped into a concatenated string AdditionalInfo field (wump wump). So they'll all have a getAdditionalInfo method, a getName, etc, and if there's any fields that don't line up they can do something special with that one.
So that makes me feel like the Request itself should not necessarily be subclassed but could contain a reference to an ISubjectable (or whatever) that implements the interface needed to get the values to send across the webservice. This sounds pretty decent and prevents a lot of "if the subject is an employee then do this..."
However, I would still at times need to access the additional fields that only a certain type of subject has, for example on a display or edit page, so that brings me right back to "if subject is instance of an employee then go to the edit employee page..." This may be unavoidable though and if so I'm ok with that.
Just for completeness I'll mention the "union of all possible fields" approach -- don't think I'd care to do that one either.
Is the interface approach the most sensible or am I going about it wrong? Thanks.
A generic solution comes to mind; that is, if the language you're using supports it:
class Request<T extends Subject> {
private T subject;
public void setSubject(T subject) {
this.subject = subject;
}
public T getSubject() {
return subject;
}
}
class EmployeeRequest extends Request<Employee> {
// ...
}
class ConsultantRequest extends Request<Consultant> {
// ...
}
You could similarly make the setSubject method abstract as you've described in your post, and then have separate implementations of it in your subclasses. Or you may not even need to subclass the Request class:
Request<Employee> employeeRequest = new Request<>();
employeeRequest.setSubject(/* ... */);
// ...
int employeeId = employeeRequest.getSubject().getEmployeeId();

Business Entity - should lists be exposed only as ReadOnlyCollections?

In trying to centralize how items are added, or removed from my business entity classes, I have moved to the model where all lists are only exposed as ReadOnlyCollections and I provide Add and Remove methods to manipulate the objects in the list.
Here is an example:
public class Course
{
public string Name{get; set;}
}
public class Student
{
private List<Course>_courses = new List<Course>();
public string Name{get; set;}
public ReadOnlyCollection<Course> Courses {
get{ return _courses.AsReadOnly();}
}
public void Add(Course course)
{
if (course != null && _courses.Count <= 3)
{
_courses.Add(course);
}
}
public bool Remove(Course course)
{
bool removed = false;
if (course != null && _courses.Count <= 3)
{
removed = _courses.Remove(course);
}
return removed;
}
}
Part of my objective in doing the above is to not end up with an Anemic data-model (an anti-pattern) and also avoid having the logic that adds and removes courses all over the place.
Some background: the application I am working with is an Asp.net application, where the lists used to be exposed as a list previously, which resulted in all kinds of ways in which Courses were added to the Student (some places a check was made and others the check was not made).
But my question is: is the above a good idea?
Yes, this is a good approach, in my opinion you're not doing anything than decorating your list, and its better than implementing your own IList (as you save many lines of code, even though you lose the more elegant way to iterate through your Course objects).
You may consider receiving a validation strategy object, as in the future you might have a new requirement, for ex: a new kind of student that can have more than 3 courses, etc
I'd say this is a good idea when adding/removing needs to be controlled in the manner you suggest, such as for business rule validation. Otherwise, as you know from previous code, there's really no way to ensure that the validation is performed.
The balance that you'll probably want to reach, however, is when to do this and when not to. Doing this for every collection of every kind seems like overkill. However, if you don't do this and then later need to add this kind of gate-keeping code then it would be a breaking change for the class, which may or may not be a headache at the time.
I suppose another approach could be to have a custom descendant of IList<T> which has generic gate-keeping code for its Add() and Remove() methods which notifies the system of what's happening. Something like exposing an event which is raised before the internal logic of those methods is called. Then the Student class would supply a delegate or something (sorry for being vague, I'm very coded-out today) when instantiating _courses to apply business logic to the event and cancel the operation (throw an exception, I imagine) if the business validation fails.
That could be overkill as well, depending on the developer's disposition. But at least with something a little more engineered like this you get a single generic implementation for everything with the option to add/remove business validation as needed over time without breaking changes.
I've done that in the past and regretted it: a better option is to use different classes to read domain objects than the ones you use to modify them.
For example, use a behavior-rich Student domain class that jealously guards its ownership of courses - it shouldn't expose them at all if student is responsible for them - and a StudentDataTransferObject (or ViewModel) that provides a simple list of strings of courses (or a dictionary when you need IDs) for populating interfaces.

Is this a ddd anti-pattern?

Is it a violation of the Persistance igorance to inject a repository interface into a Entity object Like this. By not using a interface I clearly see a problem but when using a interface is there really a problem? Is the code below a good or bad pattern and why?
public class Contact
{
private readonly IAddressRepository _addressRepository;
public Contact(IAddressRepository addressRepository)
{
_addressRepository = addressRepository;
}
private IEnumerable<Address> _addressBook;
public IEnumerable<Address> AddressBook
{
get
{
if(_addressBook == null)
{
_addressBook = _addressRepository.GetAddresses(this.Id);
}
return _addressBook;
}
}
}
It's not exactly a good idea, but it may be ok for some limited scenarios. I'm a little confused by your model, as I have a hard time believing that Address is your aggregate root, and therefore it wouldn't be ordinary to have a full-blown address repository. Based on your example, you probably are actually using a table data gateway or dao rather than a respository.
I prefer to use a data mapper to solve this problem (an ORM or similar solution). Basically, I would take advantage of my ORM to treat address-book as a lazy loaded property of the aggregate root, "Contact". This has the advantage that your changes can be saved as long as the entity is bound to a session.
If I weren't using an ORM, I'd still prefer that the concrete Contact repository implementation set the property of the AddressBook backing store (list, or whatever). I might have the repository set that enumeration to a proxy object that does know about the other data store, and loads it on demand.
You can inject the load function from outside. The new Lazy<T> type in .NET 4.0 comes in handy for that:
public Contact(Lazy<IEnumerable<Address>> addressBook)
{
_addressBook = addressBook;
}
private Lazy<IEnumerable<Address>> _addressBook;
public IEnumerable<Address> AddressBook
{
get { return this._addressBook.Value; }
}
Also note that IEnumerable<T>s might be intrinsically lazy anyhow when you get them from a query provider. But for any other type you can use the Lazy<T>.
Normally when you follow DDD you always operate with the whole aggregate. The repository always returns you a fully loaded aggregate root.
It doesn't make much sense (in DDD at least) to write code as in your example. A Contact aggregate will always contain all the addresses (if it needs them for its behavior, which I doubt to be honest).
So typically ContactRepository supposes to construct you the whole Contact aggregate where Address is an entity or, most likely, a value object inside this aggregate.
Because Address is an entity/value object that belongs to (and therefore managed by) Contact aggregate it will not have its own repository as you are not suppose to manage entities that belong to an aggregate outside this aggregate.
Resume: always load the whole Contact and call its behavior method to do something with its state.
Since its been 2 years since I asked the question and the question somewhat misunderstood I will try to answer it myself.
Rephrased question:
"Should Business entity classes be fully persistance ignorant?"
I think entity classes should be fully persistance ignorant, because you will instanciate them many places in your code base so it will quickly become messy to always have to inject the Repository class into the entity constructor, neither does it look very clean. This becomes even more evident if you are in need of injecting several repositories. Therefore I always use a separate handler/service class to do the persistance jobs for the entities. These classes are instanciated far less frequently and you usually have more control over where and when this happens. Entity classes are kept as lightweight as possible.
I now always have 1 Repository pr aggregate root and if I have need for some extra business logic when entities are fetched from repositories I usually create 1 ServiceClass for the aggregate root.
By taking a tweaked example of the code in the question as it was a bad example I would do it like this now:
Instead of:
public class Contact
{
private readonly IContactRepository _contactRepository;
public Contact(IContactRepository contactRepository)
{
_contactRepository = contactRepository;
}
public void Save()
{
_contactRepository.Save(this);
}
}
I do it like this:
public class Contact
{
}
public class ContactService
{
private readonly IContactRepository _contactRepository;
public ContactService(IContactRepository contactRepository)
{
_contactRepository = contactRepository;
}
public void Save(Contact contact)
{
_contactRepository.Save(contact);
}
}