OO Design Modeling - oop

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.

Related

Concrete example for the definition of parallel inheritance

While reading Dive Into Design Patterns by Alexander Shvets, I stumbled across the following statement in the section "Favor Composition Over Inheritance":
Trying to reuse code through inheritance can lead to creating parallel inheritance hierarchies
According to this site the definition of parallel inheritance is the situation in which subclassing a class requires creating yet another subclass elsewhere. I'm interested in knowing what would be this kind of scenario, where we'd have to subclass all over the place, and further more the why of it: why would we have to create the subclass elsewhere? Does the need arise from the context and the problem we are trying to solve, or is it induced by the structure of the (at least) two class hierarchies and composition between them? While here is an attempt to give a mathematical definition for the parallel inheritance, the need for the implication is not clear to me.
I understand this like that. Imagine you have
public abstract class CarBase
{
// all cars run on liquid fuel, right? This is 1955
public decimal FuelVolume { get; set; }
}
Then you inherit this and create your PUTruck, SportsCar, Sedan etc
Suddenly, this is 2022 and you have Electric car. You will probably do
public abstract class ElectricCarBase : CarBase
{
public decimal ChargeVolume { get; set; }
}
^^ this will come with all the nastiness of unused and unneeded properties, bunch of noise, like Antifreeze and fuel lines. And you endup in parallel inheritance. You will need to create all sort of adapters to support all this..
Enter "Composition Over Inheritance"
public abstract class CarBase
{
public List<IFuelProvider> FuelSources { get; set; }
}
public interface IFuelProvider
{
public FuelType TypeOfFuel { get; set; }
public string MeasureUnit { get; set; }
public int FuelUnits { get; set; }
}
Now, you can support Gas, Electric or Hybrid
This is my understanding. Welcome to disagree
When it comes to inheritance, it seems we can always take examples from the Animal Kingdom. So we have a class hierarchy of Animal like this.
interface Animal {
void eat(Food someFood);
}
But every Animal has its own special Food. So when we subclass Animal with Dog we need to subclass Food with DogFood and when we subclass Animal with Cat we need to subclass Food with CatFood and so on.
Parallel hierarchies can occur naturally in a problem domain, in which case it may be sensible to model them the same way in code. But parallel hierarchies can also occur artificially in a solution domain, and that verbosity may be undesirable.
On StackOverflow, the syntactic question that often arises from this scenario is, how do I make sure my Animal doesn't eat the wrong Food?

Is there a common name for this code smell?

I refer to it as the "delivery boy". I've seen several variants of it but the issue is that a class has dependency for the sole purpose of passing it on to collaborators and never using the dependency itself.
(I'm using PHP because it's what I'm most familiar with but this is language agnostic)
class Dependency{}
class B {
public function setDependency(Dependency $dependency) {
//...
}
}
class A {
private $b;
private $dependency;
public function __construct(Dependency $dependency, B $b) {
$this->dependency = $dependency;
$this->b = $b;
}
public function foo() {
$this->b->setDependency($this->dependency);
}
}
Probably the most common variant I see in the wild is abusing inheritance for this purpose, having a property in the parent class which exists so that the child classes have access to the dependency even if the parent class never actually uses the dependency itself.
class Dependency{}
class A {
protected $dependency;
public function __construct(Dependency $dependency) {
$this->dependency = $dependency;
}
}
class B extends A {
public function foo() {
$this->dependency->bar();
}
}
I see this in code far more than I'd like and it doesn't make me very happy! I just wondered if there was a name for this so that I can link people to reading materials on why it's a bad idea. As it stands, I don't know what to search for!
I'm not aware of any name, but I kind of like Delivery boy... though I suppose some might consider the name borderline offensive.
Typically this problem is solved with either Dependency Injection or a Service Locator, although way too many people use Singleton for this (inappropriately).
I'm not familiar enough with PHP to know if PHP offers a real DI solution (as opposed to poor man's DI), but I think a service locator would be acceptable if there isn't (even though service locator is often a code smell in itself).
The problem related to inheritance in the second snippet looks like to me "Broken Hierarchy". This smell occurs when the base class and its derived class do not share an IS-A relationship. It is very common to find code that uses inheritance just for convenience (for reuse) and not because it makes sense to have a hierarchy where the participating classes are are related (by IS-A relationship).
(I borrowed the smell terminology (i.e. Broken Hierarchy) from the book "Refactoring for software design smells")

How to decide whether use IS A or HAS A Relation

public class B {
public String getMe()
{
return "Some";
}
}
Assume that i have a above class , by which parameters should we decide what to use ?? Whether is a or Has a Relation ??
HAS - A
public class A {
public static void main(String args[])
{
B b = new B();
System.out.println(b.getMe());
}
}
or
public class A extends B
{
public static void main(String args[])
{
A b = new A();
System.out.println(b.getMe());
}
}
Depends on the logical relation. It just needs to make sense.
Example:
Lets say you have Animal classes.
So you have these classes: Animal, Dog, Cat , Leopard, Fur, Feet
Cat and Dog IS A Animal.
Leopard IS A Cat.
Animal HAS A Fur, Feet.
In a nutshell:
IS A relationship means you inherit and extend the functionality of the base class.
HAS A relationship means the class is using another class, so it has it as a member.
There are 4 types of relations possible :
Generalization (IS A) : Which is implemented using inheritance like you did above. It's used when class A has all the same feature of B and you want to add some more features. So you simply extend B and add the new features.
Aggregation (HAS A) : This is a bit weaker relation than generalization. You use this relation when the object of A owns objects of B or is composed of objects of B (may be among other objects of other classes). The first type is called shared aggregation, the second is called composition. In aggregation and composition there usually an object controlling the life of the other object (it instantiates it and destroys it as it needs).
Association: In association, the classes simply know about each other's so it's weaker than aggregation. The objects do not control each other's life.
Usage : It's the weakest relation of two classes and it means simply that one class may appear as a type in a method parameter or is used internally in code.
In your example, it should be aggregation (HAS A) if A has a field of type B. But if it just creates instance of B to be used in code internally and the object is disposed from memory when the scope ends then it's neither IS A nor HAS A. It's just a usage relation.
In simple term:
"is a" represent the inheritence/extends
"has a" represents the delegation/association
for example:
House is a Building (inheritance)
House has a door(s) (association)
Here is one of the best resources I used for understanding OOP: http://chortle.ccsu.edu/CS151/cs151java.html (part 6 & 10)
is-a is like for example, a Dog is an Animal or a Cat is an Animal or It is like "a person is that-kind of a person". Is-a relationships have other objects' properties, like here "Animal" is a class(object) and etc.
The has-a relationship is like, an object has its own properties, for example, Fish has Gills or pants have pockets ... something like that.

How do I implement multiple kinds of an object in 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

Object Oriented Design Interview [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Any advice on solving this problem?
Well, here's one good one that I came up with - utilizing OOP overriding, subclass and superclass:
namespace Animals{
// base class Animal
class Animal{
public void eat(Food f){
}
}
class Carnivore extends Animal{
public void eat(Meat f){
}
}
class Herbivore extends Animal{
public void eat(Plant f){
}
}
class Omnivore extends Animal{
public void eat(Food f){
}
}
}
namespace Food{
// base class Food
class Food{
}
class Meat extends Food{
}
class Plant extends Food{
}
}
I create subclasses Herbivore, Carnivore and Omnivore from the superclass Animal and override the eat method with the type of food that it can actually eat.
So:
Plant grass = new Plant();
Herbivore deer = new Herbivore();
deer.eat(grass); // ok
Plant grass2 = new Plant();
Carnivore tiger = new Carnivore();
tiger.eat(grass2); // not ok.
Meat deer2 = new Meat();
tiger.eat(deer2); // ok
Well, the final problem is that, when you specify that deer is a Herbivore, you can't make it a Meat for tiger to eat. However at the end of the day, this should be sufficient for solving the interview problem whilst not putting the interviewer to sleep.
There's a wonderful poster for the Liskov Substitution Principle that says, "If it looks like a duck, quacks like a duck, but needs batteries, you've probably got the wrong abstraction." And that's the quick answer - some of the objects can be both animals and food, so unless you're willing to go the route of multiple inheritance, then the classification schema is all wrong.
Once you've cleared that hurdle, the rest is open-ended, and you can bring in other design principles. For instance, you could add an IEdible interface that allows objects to be consumed. You might go aspect-oriented, and add decorators for carnivore and herbivore, and that would allow consumption of only the right class of objects.
The point is to be able to think on your feet, to see and explain various aspects of a problem, and to communicate well. And perhaps not to get stuck on a "one right answer" limitation.
I'd tell him to scratch that. It's a horrible abstraction. Not to mention we're not given any context. Abstractions don't come out of thin air, or out of an "idea" of what's "right". Show me what problem are you trying to solve first, so we can evaluate this abstraction.
If no context is provided, then I'll just assume/make-up my own: you want some types of objects to be able to eat other types of objects. Nothing more, nothing less.
Make an Eatable interface (or you can call it Food, if you want), and since we have no context what so ever, I'll assume it's a toy console program, that just prints:
<X> ate <Y>
so all we need for this interface is a getFoodName() method.
For error checking, you can create a bunch of isXFoodType methods, for instance, isGrassFoodType(), isMeatFoodType(), etc. The Cow's implementation of Eat(Eatable e) would check for isGrassFoodType(), and when fails, prints:
"Cow can't eat " + e.getFoodName()
Alan Kay, who coined the term "object-oriented programming", has said "OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things".
Trying to fix this "problem" in the data model sounds to me like the opposite of late-binding: why do you need the compiler to enforce this? I wouldn't worry about changing the model at all. If you're passed something you can't eat, you throw an exception -- just like in real life, pretty much!
Food should be an interface, therefore Plant and Animal could be Food too.
abstract Animal class should have eat method that take Food as parameter.
subclasses of Animal: Carnivore, Herbivore and Omnivore should have their own version of eat.
For example for Carnivore:
private void eat(Food food)
{
if(food instanceof Animal)
{
happilyEat();
}
else
{
sniff&TurnAway();
}
}
The Problems solved.
But for a better design, Carnivore, Herbivore and Omnivore should be interfaces too, as they are not the proper way of tagging the animals.
This is easy with Generics in C# btw:
public class Food
{
}
public abstract class Animal<T> : Meat where T:Food
{
public abstract void Eat(T food);
}
public class Herbivore : Animal<Plant>
{
public override void Eat(Plant food)
{
Console.WriteLine("Herbivore eats plants.");
}
}
public class Omnivore : Animal<Food>
{
public override void Eat(Food food)
{
Console.WriteLine("Omnivore eats food.");
}
}
public class Carnivore : Animal<Meat>
{
public override void Eat(Meat food)
{
Console.WriteLine("Carnivore eats meat.");
}
}
public class Plant : Food
{
}
public class Meat : Food
{
}
public class Cow : Herbivore
{
}
public class Tiger : Carnivore
{
}
public class Human : Omnivore
{
}
Usage:
var human = new Human();
var tiger = new Tiger();
var cow = new Cow();
var plant = new Plant();
human.Eat(cow);
tiger.Eat(human);
cow.Eat(tiger); // this doesn't compile
tiger.Eat(plant); // neither does this
Here's some thoughts on that interview question:
I agree with Cylon Cat: This kind of abstraction doesn't work well without multiple inheritance (even if it's Java-like interfaces.)
I would create two forms of inheritance:
Animal:
Carnivore
Herbivore
Food:
Meat
Vegetable
The "eat" method of the two kinds of animals (I'm ignoring omnivores, insectivores, and many other kinds) would be specialized for the different kinds of food. If we're using a language like Java, then Food would be an interface.
Any animal is food, any vegetable is food. And in fact a tiger can be eaten by a cow. (The prion disease scrapie is spread by feeding infected sheep neural tissue to uninfected sheep.)
You could have a hierarchy of species, ala Linnaeus, both animal and vegetable. Each species is a Singleton, and it has a List<Species> that records its typical diet. Ditch the Food hierarchy entirely, it only confuses things.
And, if your only problem is recording diet for each species, then the multiple Species classes are unnecessary. Just have a single Species class with the species name as one instance variable and the List<Species> as another.
There's no one best solution. You might want to make this a community wiki, as that's generally the accepted practice for subjective questions.
I'd think about what actually would make the best parent class for the hierarchies, and try to figure out what "best" means in that context.
Everything there are Things, which could have a Name attribute. But everything there at some level is Food; if it can eat something, something can eat it. I might make Food the parent class, and give it a method that returns a boolean to check if the parameter object can eat the current object.
So,
class Food {
boolean canBeEatenBy(Food hungryObject)
String name
}
That seems the simplest class hierarchy that fits everything I might need on a first pass?
That said, the important part in most interview questions is the feel you get for the interviewee, not so much the exact answer that they give.
Double dispatch, perhaps?
If you expect the system to get very big I would suggest subclassing plant/meat and herbivore/carnivore/omnivore.
Ensure the system has a standard interface for all plant/animals called getFoodName() and getFoodType(), you could enforce this by creating a parent class for plants/animals called species.
The problem I would see with the subclassing plant/meat and carnivore/herbivore is that a meerkat is carnivore but it likely can't eat a rhino(there may be a better example), so some restrictions are needed beyond "I eat meat, you eat plants".
If it wasn't going to get incredibly big and you wanted to be neurotic about it, you could store static enums of allowable foods for each subclass of animal. So tiger could store deer, antelope etc.