質問

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.

役に立ちましたか?

解決

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.

他のヒント

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.

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.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top