I just read about Value Objects, being immutable and described as:
A small simple object, like money or a date range, whose equality isn't based on identity.
Looking at my currently existing entities I figured I could make pretty much everything that's not an entity a value object.
Let's say I have an entity class User.
class User
{
public $id;
public $firstname;
public $lastname;
public $email;
}
I could make it consist of the value objects Id, FirstName, LastName, Email and Password, because none of these User attributes equality are based on identity, right? But then again I could probably go even further and make more VOs Int, String, Name (which consists of FirstName and LastName VOs), etc.
Where do I draw he line to prevent over-engineering?
Is it normal for a domain to contain that many VOs?
Is my understanding of value objects even right?
Yes, it is normal for a domain to contain lots of VO's if you want to set the bar of type safety and expressivity high enough -- which is generally a good thing.
No need to redefine Int and String, but identified ubiquitous language concepts should definitely have their own objects.
Admittedly, doing so is much more natural and painless in some languages than others. This can influence where you draw the line. In functional languages, for instance, it is not uncommon to wrap primitive types as in type UserId = UserId of int. Which I wouldn't bother doing in an OO language, class ceremony being what it is.
Related
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();
Assume we have class Car which MAIN field is called VIN (Vehicle Identification Number). VIN gives us a lot of information such us:
owner
place of registration
country of production
year of production
color
engine type
etc. etc
I can continue and add more information:
last known GPS coordinates
fine list
is theft (boolean)
etc. etc.
It seems reasonable to store some of information (for example year of production and engine type) right inside Car object. However storing all this information right inside Car object will make it too complicated, "overloaded" and hard to manage. Moreover while application evolves I can add more and more information.
So where is the border? What should be stored inside Car object and what should be stored outside in something like Dictionary<Car, GPSCoordinates>
I think that probably I should store "static" data inside Car object so making it immutable. And store "dynamic" data in special storages.
I would use a class called CarModel for the base attributes shared by every possible car in your application (engine size, color, registration #, etc). You can then extend this class with any number of more specific subclasses like Car, RentalCar, or whatever fits your business logic.
This way you have one clear definition of what all cars share and additional definitions for the different states cars can be in (RentalCar with its unique parameters, for example).
Update:
I guess what you're looking for is something like this (although I would recommend against it):
public class Car
{
// mandatory
protected int engineSize;
protected int color;
// optional
protected Map<String, Object> attributes = new HashMap<String, Object>();
public void set(String name, Object value)
{
attributes.put(name, value);
}
public Object get(String name)
{
return attributes.get(name);
}
}
Why this is not a good solution:
Good luck trying to persist this class to a database or design anything that relies on a well known set of attributes for it.
Nightmare to debug potential problems.
Not a very good use of OOP with regard to type definitions. This can be abused to turn the Car class into something it is not.
Just because your Car class provide a property GPSCoordinates does not mean you need to hold those coordinates internally. Essentially, that's what encapsulation is all about.
And yes, you can then add properties such as "IsInGarageNow", "WasEverDrivedByMadonna" or "RecommendedOil".
I had a discussion at work regarding "Inheritance in domain model is complicating developers life". I'm an OO programmer so I started to look for arguments that having inheritance in domain model will ease the developer life actually instead of having switches all over the place.
What I would like to see is this :
class Animal {
}
class Cat : Animal {
}
class Dog : Animal {
}
What the other colleague is saying is :
public enum AnimalType {
Unknown,
Cat,
Dog
}
public class Animal {
public AnimalType Type { get; set; }
}
How do I convince him (links are WELCOME ) that a class hierarchy would be better than having a enum property for this kind of situations?
Thanks!
Here is how I reason about it:
Only use inheritance if the role/type will never change.
e.g.
using inheritance for things like:
Fireman <- Employee <- Person is wrong.
as soon as Freddy the fireman changes job or becomes unemployed, you have to kill him and recreate a new object of the new type with all of the old relations attached to it.
So the naive solution to the above problem would be to give a JobTitle enum property to the person class.
This can be enough in some scenarios, e.g. if you don't need very complex behaviors associated with the role/type.
The more correct way would be to give the person class a list of roles.
Each role represents e.g an employment with a time span.
e.g.
freddy.Roles.Add(new Employement( employmentDate, jobTitle ));
or if that is overkill:
freddy.CurrentEmployment = new Employement( employmentDate, jobTitle );
This way , Freddy can become a developer w/o we having to kill him first.
However, all my ramblings still haven't answered if you should use an enum or type hierarchy for the jobtitle.
In pure in mem OO I'd say that it's more correct to use inheritance for the jobtitles here.
But if you are doing O/R mapping you might end up with a bit overcomplex data model behind the scenes if the mapper tries to map each sub type to a new table.
So in such cases, I often go for the enum approach if there is no real/complex behavior associated with the types.
I can live with a "if type == JobTitles.Fireman ..." if the usage is limited and it makes things easer or less complex.
e.g. the Entity Framework 4 designer for .NET can only map each sub type to a new table. and you might get an ugly model or alot of joins when you query your database w/o any real benefit.
However I do use inheritance if the type/role is static.
e.g. for Products.
you might have CD <- Product and Book <- Product.
Inheritance wins here because in this case you most likely have different state associated with the types.
CD might have a number of tracks property while a book might have number of pages property.
So in short, it depends ;-)
Also, at the end of the day you will most likely end up with a lot of switch statements either way.
Let's say you want to edit a "Product" , even if you use inheritance, you will probably have code like this:
if (product is Book)
Response.Redicted("~/EditBook.aspx?id" + product.id);
Because encoding the edit book url in the entity class would be plain ugly since it would force your business entites to know about your site structure etc.
Having an enum is like throwing a party for all those Open/Closed Principle is for suckers people.
It invites you to check if an animal is of a certain type and then apply custom logic for each type. And that can render horrible code, which makes it hard to continue building on your system.
Why?
Doing "if this type, do this, else do that" prevents good code.
Any time you introduce a new type, all those ifs get invalid if the new type is not handled. In larger systems, it's hard to find all those ifs, which will lead to bugs eventually.
A much better approach is to use small, well-defined feature interfaces (Interface segregation principle).
Then you will only have an if but no 'else' since all concretes can implement a specific feature.
Compare
if (animal is ICanFly flyer)
flyer.Sail();
to
// A bird and a fly are fundamentally different implementations
// but both can fly.
if (animal is Bird b)
b.Sail();
else if (animal is Fly f)
b.Sail();
See? the former one needs to be checked once while the latter has to be checked for every animal that can fly.
Enums are good when:
The set of values is fixed and never or very rarely changes.
You want to be able to represent a union of values (i.e. combining flags).
You don't need to attach other state to each value. (Java doesn't have this limitation.)
If you could solve your problem with a number, an enum is likely a good fit and more type safe. If you need any more flexibility than the above, then enums are likely not the right answer. Using polymorphic classes, you can:
Statically ensure that all type-specific behavior is handled. For example, if you need all animals to be able to Bark(), making Animal classes with an abstract Bark() method will let the compiler check for you that each subclass implements it. If you use an enum and a big switch, it won't ensure that you've handled every case.
You can add new cases (types of animals in your example). This can be done across source files, and even across package boundaries. With an enum, once you've declared it, it's frozen. Open-ended extension is one of the primary strengths of OOP.
It's important to note that your colleague's example is not in direct opposition to yours. If he wants an animal's type to be an exposed property (which is useful for some things), you can still do that without using an enum, using the type object pattern:
public abstract class AnimalType {
public static AnimalType Unknown { get; private set; }
public static AnimalType Cat { get; private set; }
public static AnimalType Dog { get; private set; }
static AnimalType() {
Unknown = new AnimalType("Unknown");
Cat = new AnimalType("Cat");
Dog = new AnimalType("Dog");
}
}
public class Animal {
public AnimalType Type { get; set; }
}
This gives you the convenience of an enum: you can do AnimalType.Cat and you can get the type of an animal. But it also gives you the flexibility of classes: you can add fields to AnimalType to store additional data with each type, add virtual methods, etc. More importantly, you can define new animal types by just creating new instances of AnimalType.
I'd urge you to reconsider: in an anemic domain model (per the comments above), cats don't behave differently than dogs, so there's no polymorphism. An animal's type really is just an attribute. It's hard to see what inheritance buys you there.
Most importantly OOPS means modeling reality. Inheritance gives you the opportunity to say Cat is an animal. Animal should not know if its a cat now shout it and then decide that it is suppose to Meow and not Bark, Encapsulation gets defeated there. Less code as now you do not have to do If else as you said.
Both solutions are right.
You should look which techniques applies better to you problem.
If your program uses few different objects, and doesn't add new classes, its better to stay with enumerations.
But if you program uses a lot of different objects (different classes), and may add new classes, in the future, better try the inheritance way.
I have a simple question about object oriented design but I have some difficulties figuring out what is the best solution. Say that I have an object with some methods and a fairly large amount of properties, perhaps an Employee object. Properties, like FirstName, Address and so on, which indicates a data structure. Then there could be methods on the Employee object, like IsDueForPromotion(), that is more of OO nature.
Mixing this does not feel right to me, I would like to separate the two but I do not know how to do it in a good way. I have been thinking about putting all property data in a struct and have an internal struct object inside the employee object, private EmployeeStruct employeData ...
I am not sure this is a really good idea however, maybe I should just have all methods and proerties in the same class and go with that. Am I making things to complicated if I separate data from methods?
I would very much appreciate if someone have any ideas about this.
J
Wasn't the idea of OO-design to encapsulate data and the corresponding methods together?
The question here is how the Employee object could possibly know about begin due for promotion. I guess that method belongs somewhere else to a class which has the informations to decicde that. really stupid example Manager m = new Manager(); manager.IsDueForPromotion(employeeobject);
But other methods to access the fields of Employee belong to this class.
The question I raised about IsDueForPromotion depends on you application and if your Employee is a POJO or DTO only or if it can have more "intelligent" methods associated too.
if your data evolves slower than behaviour you may want to give a try to Visitor pattern:
class Employee {
String name;
String surName;
int age;
// blah blah
// ...getters
// ...setters
// other boilerplate
void accept(EmployeeVisitor visitor) {
visitor.visitName(name);
visitor.visitAge(age);
// ...
}
}
interface EmployeeVisitor {
void visitName(String name);
void visitAge(int age);
}
with this design you can add new operations without changing the Employee class.
Check also use the specification pattern.
Object operations (methods) are supposed to use the properties. So I feel its better to leave them together.
If it does not require properties, its a kind of utility method and should be defined else ware, may in some helper class.
Well, OO is a way of grouping data and functionality that belong together in the same location. I don't really see why you would make an exception 'when there is a lot of data'. The only reason I can think of is legibility.
Personally I think you would be making things needlessly complex by coming up with a separate struct to hold your data. I'm also conflicted as to wether this would be good practice. On the one hand, how a class implements it's functionality, or stores it's data is supposed to be hidden from the outside world. On the other hand, if data belongs to a class, it feels unnatural to store it in something like a struct.
It may be interesting to look at the data you have and see if it can be modeled into smaller domain objects. For example, have an Address object that holds a street, housenumber, state, zip, country, etc value. That way, your Employee object will just hold an Address object. The Address object could then be reused for your Company objects etc.
The basic principle of Object Oriented programming is grouping data such as FirstName and Address with the functionality that goes with it, such as IsDueForPromotion(). It doesn't matter how much data the object is holding, it will still hold that data. The only time you want to remove data from an object is if it has nothing to do with that object, like storing the company name in the Employee object when it should be stored in a company object.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Which class design is better and why?
public class User
{
public String UserName;
public String Password;
public String FirstName;
public String LastName;
}
public class Employee : User
{
public String EmployeeId;
public String EmployeeCode;
public String DepartmentId;
}
public class Member : User
{
public String MemberId;
public String JoinDate;
public String ExpiryDate;
}
OR
public class User
{
public String UserId;
public String UserName;
public String Password;
public String FirstName;
public String LastName;
}
public class Employee
{
public User UserInfo;
public String EmployeeId;
public String EmployeeCode;
public String DepartmentId;
}
public class Member
{
public User UserInfo;
public String MemberId;
public String JoinDate;
public String ExpiryDate;
}
The question is simply answered by recognising that inheritance models an "IS-A" relationship, while membership models a "HAS-A" relationship.
An employee IS A user
An employee HAS A userinfo
Which one is correct? This is your answer.
I don't like either one. What happens when someone is both a member and an employee?
Ask yourself the following:
Do you want to model an Employee IS a User? If so, chose inheritance.
Do you want to model an Employee HAS a User information? If so, use composition.
Are virtual functions involved between the User (info) and the Employee? If so, use inheritance.
Can an Employee have multiple instances of User (info)? If so, use composition.
Does it make sense to assign an Employee object to a User (info) object? If so, use inheritance.
In general, strive to model the reality your program simulates, under the constraints of code complexity and required efficiency.
Nice question although to avoid distractions about right and wrong I'd consider asking for the pros and cons of each approach -- I think that's what you meant by which is better or worse and why. Anyway ....
The First Approach aka Inheritance
Pros:
Allows polymorphic behavior.
Is initially simple and convenient.
Cons:
May become complex or clumsy over time if more behavior and relations are added.
The Second Approach aka Composition
Pros:
Maps well to non-oop scenarios like relational tables, structured programing, etc
Is straightforward (if not necessarily convenient) to incrementally extend relations and behavior.
Cons:
No polymorphism therefore it's less convenient to use related information and behavior
Lists like these + the questions Jon Limjap mentioned will help you make decisions and get started -- then you can find what the right answers should have been ;-)
I don't think composition is always better than inheritance (just usually). If Employee and Member really are Users, and they are mutually exclusive, then the first design is better. Consider the scenario where you need to access the UserName of an Employee. Using the second design you would have:
myEmployee.UserInfo.UserName
which is bad (law of Demeter), so you would refactor to:
myEmployee.UserName
which requires a small method on Employee to delegate to the User object. All of which is avoided by the first design.
You can also think of Employee as a role of the User (Person). The role of a User can change in time (user can become unemployed) or User can have multiple roles at the same time.
Inheritance is much better when there is real "is a" relation, for example Apple - Fruit. But be very careful: Circle - Ellipse is not real "is a" relation, because cirlce has less "freedom" than ellipse (circle is a state of ellipse) - see: Circle Ellipse problem.
The real questions are:
What are the business rules and user stories behind a user?
What are the business rules and user stories behind an employee?
What are the business rules and user stories behind a member?
These can be three completely unrelated entities or not, and that will determine whether your first or second design will work, or if another completely different design is in order.
Neither one is good. Too much mutable state. You should not be able to construct an instance of a class that is in an invalid or partially initialized state.
That said, the second one is better because it favours composition over inheritance.
Stating your requirement/spec might help arrive at the 'best design'.
Your question is too 'subject-to-reader-interpretation' at the moment.
Here's a scenario you should think about:
Composition (the 2nd example) is preferable if the same User can be both an Employee and a Member. Why? Because for two instances (Employee and Member) that represent the same User, if User data changes, you don't have to update it in two places. Only the User instance contains all the User information, and only it has to be updated. Since both Employee and Member classes contain the same User instance, they will automatically both contain the updated information.
Three more options:
Have the User class contain the supplemental information for both employees and members, with unused fields blank (the ID of a particular User would indicate whether the user was an employee, member, both, or whatever).
Have an User class which contains a reference to an ISupplementalInfo, where ISupplementalInfo is inherited by ISupplementalEmployeeInfo, ISupplementalMemberInfo, etc. Code which is applicable to all users could work with User class objects, and code which had a User reference could get access to a user's supplemental information, but this approach would avoid having to change User if different combinations of supplemental information are required in future.
As above, but have the User class contain some kind of collection of ISupplementalInfo. This approach would have the advantage of facilitating the run-time addition of properties to a user (e.g. because a Member got hired). When using the previous approach, one would have to define different classes for different combinations of properties; turning a "member" into a "member+customer" would require different code from turning an "employee" into an "employee+customer". The disadvantage of the latter approach is that it would make it harder to guard against redundant or inconsistent attributes (using something like a Dictionary<Type, ISupplementalInfo> to hold supplemental information could work, but would seem a little "bulky").
I would tend to favor the second approach, in that it allows for future expansion better than would direct inheritance. Working with a collection of objects rather than a single object might be slightly burdensome, but that approach may be better able than the others to handle changing requirements.