How do I implement multiple kinds of an object in OOP? - oop

I have multiple kinds of an object, say Car for example.
Do I have each kind in an inherited class/subclass of Car?
Do I place these under a cartype namespace so as not to mess up the main namespace?
Then later when I need an array of cars, should I declare it as var currentCars():Car or var currentCars():Object? Would the former support any subclass of Car?

Specific answers are difficult because they really depend on the particulars of your problem space, but in general you would use subclasses of Car if all kinds of Car shared some functionality. E.g.:
public class Car {
public void Start() { }
}
And then you could have different types of Car:
public class Sedan : Car {
public void OpenAllFourDoors() { }
}
public class Coupe : Car {
public void OpenAllTwoDoors() { }
}
You don't generally need to put the class hierarchy into its own namespace, there are other sets of guidance for namespace definitions. Typically, expect namespaces to take the form of something like CompanyName.ProductName.ModuleName or something similar.
Later, when you need an array (or, more commonly, a collection) of cars, you would create a collection of Car. When you grab a reference from this collection, though, you won't be able to OpenAllFourDoors or OpenAllTwoDoors because you won't know which subclass of Car you're working with.
(Apologies for C#-centric syntax)

You can have an inifinite number of classes inheriting from your Car class as long as you don't have overriden methods that conflict.
As for namespaces, I usually put the classes that inherit from another one in the same namespace, not sure if not being in the same namespace works though.
Oh and when you need an array, you declare it just like any other data type.
You see, when you declare a class Car you create a data type Car.
So when you need to declare an array of cars, you go like this:
var currentCars():Car

Related

Should there be one or multiple XXXRepository instances in my system, with DDD?

There's something that has been bothering from my DDD readings. From what I've seen, it seems as if there is only repository instance for each given aggregate root type in my system.
Consider, for instance, the following imaginary situation as an abstraction of a deeper domain model:
When coding in a "standard-style" I'd consider that each Owner in my system would have its own collection of cars, so there would be an equal number of Car collections (should I call it Repositories?) as there are Owners. But, as stated previously, it seems as if in DDD I should only have one CarRepository in the whole system (I've seen examples in which they are accessed as static classes), and to do simple operations such as adding cars to the Owner, I should make use of a domain-service, which seems to be, for the simple case, not very API friendly.
Am I right about only having one CarRepository instantiated in my system (Singleton), or am I missing something? I'd like to strive for something like
public void an_owner_has_cars() throws Exception {
Owner owner = new Owner(new OwnerId(1));
CarId carId = new CarId(1);
Car car = new Car(carId);
owner.addCar(car);
Assert.assertEquals(car, owner.getCarOf(carId));
}
but that doesn't seem to be possible without injecting a repository into Owner, something that seems to be kind of forbidden.
A repository does not represent a collection that belongs to another entity. The idea is that it represents the entire collection of entities.
So in your example Car is an entity and probably an aggregate. So your model is OK on a conceptual level but you need to split the tight coupling between Car and Owner since Owner is most definitely an AR and, in your current model, deleting it would mean all cars belonging to it should be deleted also.
What you are probably after is something like this:
public class Owner {
private IEnumerable<OwnedCar> cars;
}
public class OwnedCar {
public Guid CarId { get; set; }
}
Or, as an alternative to a VO:
public class Owner {
private IEnumerable<Guid> carsOwned;
}
So one AR should not reference another AR instance.
Another point is that you probably do not want to inject repositories into entities since that may indicate a bit of a design flaw (somewhat of a code smell).
To get the owned cars into the Owner would be the job of the OwnerRepository since it is part of the same aggregate. There would be no OwnedCarRepository since it is a value object.
100% for sure, you don't have to make a singleton CarRepository unless you're working in a legacy system which doesn't use any dependency inejction mechanism.
If you find you need to inject CarRepository to Owner to retrieve cars belong to a specific owner, maybe it's a hint that you should re-model there relationship like:
public class Owner {
}
public class Car {
private Owner owner;
}
And use CareRepository to achieve your goal:
public interface CarRepository {
List<Car> findBy(String onwer);
}
And just a speculation, the static part maybe refer to DomainEvents, like:
public class Owner {
public long quantityOfCarsOwned() {
return DomainEvents.raise(new SumCarsEvent(this));//static
}
}
public class SumCarsEventHandler {
private CarRepository carRepository;//inject this, SumCarsEventHandler should be a statless bean managed by container like spring
public long handle(SumCarsEvent event) {
return carRepository.countBy(event.getOwner());
}
}
In very simple case, it's just too complicated I think.

OO Design Modeling

How to model a domain when you have a base class and 2 classes extending this base class and only one of derived class has a relationship with another object.
Example:
public abstract class Base
{
public abstract void method();
}
public class1 extends Base
{
public void method()
{
do some stuff
}
}
public class2 extends Base
{
private Class3 class3;
public void method()
{
do other stuff
}
public Class3 getClass3(){...}
public void setClass3(Class3 class3){...}
}
Is this model breaking Liskov principle? I think so because of this relation with class3, so we have to figure out how to model without this relation or to move this relation to Base. If I have a part of program that deal with Class2 to handle the relation whith Class3 I can't work with base class without cast to class2.
Is this thought right?
Clarifying...
Let's think in learning model. We have Courses and CourseClasses. We can also have a online courses and presencial courses. In presencial courses we may face with cost of this training. So costs only make sense to presencial environment. CourseClasses could have range dates or quatitative dates.
Today I have this model:
Course
{
...
}
public abstract class CourseClass
{
private Course course;
// getter and setter to course
public abstract Enrollment enroll(Person student);
}
public class QuantitativeCourseClass
{
public Enrollment enroll(Person student)
{
// enroll for quantitative
}
}
public class RangeCourseClass
{
public Enrollment enroll(Person student)
{
// enroll for range
}
}
Now I have to deal with costs and till this moment presencial course isn't important to me but now, cost only make sense to presencial enviroment.
My problem is: I need to deal with CourseClass object in cost module because I need some stuff of courseClass, but the relationship of cost is with RangeCourseClass because QuantitativeCourseClass don't make sense to prensecial environment.
The question about liskov is about how to convence my team to make some modifications in this model.
if class3 has nothing to do with base, then it should not be in the base. You can't "break" LSP, since the compiler enforces it. downcasting is not something that is preferred, but doing so doesn't break LSP.
The purpose of inheritence is to have an "is-a" relationship. A cat is-a(n) animal. A toyota is-a car.
What you're talking about is moving the toyota emblem to the car class just because you want to make things easier. That's not good design at all.
In short, it's worse design to move things to the base class than it is to downcast to the specific class.
I think you have mixed up the direction of LSP (Liskov Substitution Principle): LSP is (strong) behavioral subtyping, not strong behavioral supertyping. So LSP is not working against your example, but for your example:
Is this model breaking Liskov principle? I think so because of this
relation with class3, so we have to figure out how to model without
this relation or to move this relation to Base. If I have a part of
program that deal with Class2 to handle the relation with Class3 I
can't work with base class without cast to class2.
Your model is not breaking LSP. If you have a part of program that uses some variable var that deals specifically with Class2 (i.e. parts not present in Base), you need to declare var to be of Class2. So no downcast is necessary. And LSP guarantees that var behaves as Base, too, so no explicit upcast is necessary, either.
As i understand, you can not view the problem without knowing the problem aspects (geometry, for example). So, i can not understand meaning of your architecture. For example, the famous LSP violation Example:
Square:Rectangle -it looks fine, when it stand in "side". But, when you start use and you put some functions around, you can see the problem.

Objects with two properties only

I am trying to decide on the best approach to the following problem:
I have a class called Desk. A desk has lots of properties. A Desk may have some objects on it. The current application specifies that it can have Pencils, Computers, or Cups on the desk. A few more objects may be added in the future. It can have one or none of each object. The Pencils have a property of Color, all of the objects have an ID and name. All of this information must be persistent so is stored in a database in some form.
Do I:
public class Desk {
public int property1;
public int property2;
...
public ISet<DeskObject> deskObjects;
}
public DeskObject {
public int deskObjectID;
public String name;
public DeskObject(name) {
this.name = name;
}
}
public Computer extends DeskObject {
DeskObject("Computer");
}
public Pencil extends DeskObject {
DeskObject("Pencil);
public Color color;
}
I also need to easily tell which objects a Desk contains in O(1) time. This means I will have to override hashcode and equals (probably by just returning the ID) for the DeskObjects so I can do set.contains(object). It seems like overkill and a misuse of objects. Surely there is a better solution?
If your domain is about desks and the objects they contain, then an object model like this is entirely warranted. The only question you need to ask yourself is this: Is this my domain model, or is it a computation model?
From the phrasing of your question, I would infer its rather the latter. Your objects do not contain any behavior (such as Desk.CleanNonRecentlyUsed()).
A domain model contains data and behavior (a true object model, I call this domain model), a computation model is data and separated behavior (procedural code).
If all your model needs to do is provide efficient lookups, you can chose any abstract representation that suits you. A lightweight object that captures just data is ok, but you could also use tuples (or to be .net specific since you mentioned GetHashCode: Annonymous classes) or just a Hashtable for the desk. Your computation model can be anything from an Index in your database (sounds reasonable in your example), a special object model, or dedicated algorithms over plain arrays.
Most of the time, it is not warranted to create a computation model when you already have a domain model. But sometimes it is.

Inheritance vs enum properties in the domain model

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.

Type conversion when iterating over a collection of super-type. Alternatives?

This is quite a common problem I run into. Let's hear your solutions. I'm going to use an Employee-managing application as an example:-
We've got some entity classes, some of which implement a particular interface.
public interface IEmployee { ... }
public interface IRecievesBonus { int Amount { get; } }
public class Manager : IEmployee, IRecievesBonus { ... }
public class Grunt : IEmployee /* This company sucks! */ { ... }
We've got a collection of Employees that we can iterate over. We need to grab all the objects that implement IRecievesBonus and pay the bonus.
The naive implementation goes something along the lines of:-
foreach(Employee employee in employees)
{
IRecievesBonus bonusReciever = employee as IRecievesBonus;
if(bonusReciever != null)
{
PayBonus(bonusReciever);
}
}
or alternately in C#:-
foreach(IRecievesBonus bonusReciever in employees.OfType<IRecievesBonus>())
{
PayBonus(bonusReciever);
}
We cannot modify the IEmployee interface to include details of the child type as we don't want to pollute the super-type with details that only the sub-type cares about.
We do not have an existing collection of only the subtype.
We cannot use the Visitor pattern because the element types are not stable. Also, we might have a type which implements both IRecievesBonus and IDrinksTea. Its Accept method would contain an ambiguous call to visitor.Visit(this).
Often we're forced down this route because we can't modify the super-type, nor the collection e.g. in .NET we may need to find all the Buttons on this Form via the child Controls collection. We may need to do something to the child types that depends on some aspect of the child type (e.g. the bonus amount in the example above).
Strikes me as odd that there isn't an "accepted" way to do this, given how often it comes up.
1) Is the type conversion worth avoiding?
2) Are there any alternatives I haven't thought of?
EDIT
Péter Török suggests composing Employee and pushing the type conversion further down the object tree:-
public interface IEmployee
{
public IList<IEmployeeProperty> Properties { get; }
}
public interface IEmployeeProperty { ... }
public class DrinksTeaProperty : IEmployeeProperty
{
int Sugars { get; set; }
bool Milk { get; set; }
}
foreach (IEmployee employee in employees)
{
foreach (IEmployeeProperty property in employee.Propeties)
{
// Handle duplicate properties if you need to.
// Since this is just an example, we'll just
// let the greedy ones have two cups of tea.
DrinksTeaProperty tea = property as DrinksTeaProperty;
if (tea != null)
{
MakeTea(tea.Sugers, tea.Milk);
}
}
}
In this example it's definitely worth pushing these traits out of the Employee type - particularly because some managers might drink tea and some might not - but we still have the same underlying problem of the type conversion.
Is it the case that it's "ok" so long as we do it at the right level? Or are we just moving the problem around?
The holy grail would be a variant on the Visitor pattern where:-
You can add element members without modifying all the visitors
Visitors should only visit types they're interested in visiting
The visitor can visit the member based on an interface type
Elements might implement multiple interfaces which are visited by different visitors
Doesn't involve casting or reflection
but I appreciate that's probably unrealistic.
I would definitely try to resolve this with composition instead of inheritance, by associating the needed properties/traits to Employee, instead of subclassing it.
I can give an example partly in Java, I think it's close enough to your language (C#) to be useful.
public enum EmployeeProperty {
RECEIVES_BONUS,
DRINKS_TEA,
...
}
public class Employee {
Set<EmployeeProperty> properties;
// methods to add/remove/query properties
...
}
And the modified loop would look like this:
foreach(Employee employee in employees) {
if (employee.getProperties().contains(EmployeeProperty.RECEIVES_BONUS)) {
PayBonus(employee);
}
}
This solution is much more flexible than subclassing:
it can trivially handle any combination of employee properties, while with subclassing you would experience a combinatorial explosion of subclasses as the number of properties grow,
it trivially allows you to change Employee properties runtime, while with subclassing this would require changing the concrete class of your object!
In Java, enums can have properties or (even virtual) methods themselves - I don't know whether this is possible in C#, but in the worst case, if you need more complex properties, you can implement them with a class hierarchy. (Even in this case, you are not back to square one, since you have an extra level of indirection which gives you the flexibility described above.)
Update
You are right that in the most general case (discussed in the last sentence above) the type conversion problem is not resolved, just pushed one level down on the object graph.
In general, I don't know a really satisfying solution to this problem. The typical way to handle it is using polymorphism: pull up the common interface and manipulate the objects via that, thus eliminating the need for downcasts. However, in cases when the objects in question do not have a common interface, what to do? It may help to realize that in these cases the design does not reflect reality well: practically, we created a marker interface solely to enable us to put a bunch of distinct objects into a common collection, but there is no semantical relationship between the objects.
So I believe in these cases the awkwardness of downcasts is a signal that there may be a deeper problem with our design.
You could implement a custom iterator that only iterates over the IRecievesBonus types.