什么是这种非明确定义的继承的正确设计模式?

时间:2014-03-21 22:50:51

标签: java design-patterns

假设我们有一个带有子类mini和sedan的类Car,两者都有相同的安全检查,我称之为一个名为safety()的常用函数,就像一个模板。所以:

class Car {
    safety() {
        check1();
        check2();
        check3();
        check4();
    }
}

class Mini extends Car {
    // use the safety() belonging to Car
}


class Sedan extends Car {
    // use the safety() belonging to Car
}

但事情发生了变化,我们有了新的类型和新的安全装置

  1. sports需要check1,check3和新的check5
  2. jeep需要check1,check4和new check6
  3. luxury只需要check2和check3
  4. 哪些设计模式可以帮助我们解决此问题?

4 个答案:

答案 0 :(得分:1)

忘记模式并以适合用例的方式实施您的课程。在你的例子中,我认为,安全性不是汽车的属性,而是某些程序应用于汽车的结果

class CrashTestDummy
{
   public Safety check(Car car) {...}
   public Safety check(Mini mini) {...}
   public Safety check(Sedan sedan) {...}
}

通过这种方式,您可以比较 Safeties,根据它们做出决策,聚合它们或随着时间的推移保存它们。

答案 1 :(得分:1)

不确定模式是什么 - 可能是Strategy - 但我会按照您的想法编写代码:

enum Check {

    Brakes {
                @Override
                boolean pass(Vehicle vehicle) {
                    return checkBrakes(vehicle);
                }
            },
    Lights {
                @Override
                boolean pass(Vehicle vehicle) {
                    return checkLights(vehicle);
                }
            },
    Steering {
                @Override
                boolean pass(Vehicle vehicle) {
                    return checkSteering(vehicle);
                }
            },
    Oil {
                @Override
                boolean pass(Vehicle vehicle) {
                    return checkOil(vehicle);
                }
            },
    Suspension {
                @Override
                boolean pass(Vehicle vehicle) {
                    return checkSuspension(vehicle);
                }
            };

    abstract boolean pass(Vehicle vehicle);
}

enum Vehicle {

    Car(Check.Brakes, Check.Lights, Check.Oil, Check.Steering),
    Mini(Car, Check.Suspension);

    Set<Check> checks = EnumSet.noneOf(Check.class);

    Vehicle(Check... checks) {
        this.checks.addAll(Arrays.asList(checks));
    }

    Vehicle(Vehicle like, Check... checks) {
        this.checks.addAll(like.checks);
        this.checks.addAll(Arrays.asList(checks));
    }

    public Set<Check> fail () {
        Set<Check> failed = EnumSet.noneOf(Check.class);
        for ( Check check : checks ) {
            if ( !check.pass(this) ) {
                failed.add(check);
            }
        }
        return failed;
    }
}

private static boolean checkBrakes(Vehicle vehicle) {
    return true;
}

private static boolean checkLights(Vehicle vehicle) {
    return true;
}

private static boolean checkSteering(Vehicle vehicle) {
    return true;
}

private static boolean checkOil(Vehicle vehicle) {
    return true;
}

private static boolean checkSuspension(Vehicle vehicle) {
    return true;
}

答案 2 :(得分:0)

在我看来,非常合适的是访客模式http://en.wikipedia.org/wiki/Visitor_pattern

有两个基本界面:

public interface Visitable {

    void accept(Visitor visitor);

}

public interface Visitor {

    void visit(Mini mini);

    void visit(Sedan sedan);

}

Visitable的示例实现可能如下所示(请注意接受方法):

public class Mini extends Car implements Visitable {

    private int miniSafetyCageCondition;

    public Mini(int breaksCondition, int miniSafetyCageCondition) {
        super(breaksCondition);
        this.miniSafetyCageCondition = miniSafetyCageCondition;
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    public int getMiniSafetyCageCondition() {
        return miniSafetyCageCondition;
    }
}

public class Sedan extends Car implements Visitable {

    private final boolean frontAirbagsPresent;

    private final boolean sideAirbagsPresent;

    public Sedan(int breaksCondition, boolean frontAirbagsPresence, boolean sideAirbagsPresent) {
        super(breaksCondition);
        this.frontAirbagsPresent = frontAirbagsPresence;
        this.sideAirbagsPresent = sideAirbagsPresent;
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    public boolean isSideAirbagsPresent() {
        return sideAirbagsPresent;
    }

    public boolean isFrontAirbagsPresent() {
        return frontAirbagsPresent;
    }
}

public class Car {

    private final int breaksCondition;

    public Car(int breaksCondition) {
        this.breaksCondition = breaksCondition;
    }

    public int getBreaksCondition() {
        return breaksCondition;
    }

}

这可能是访客的示例实现(请注意访问方法):

public class SafetyVisitor implements Visitor {

    private boolean result;

    private CarBasicCheck carBasicCheck = new CarBasicCheck();

    private MiniSpecificCheck miniSpecificCheck = new MiniSpecificCheck();

    private SedanSpecificCheck sedanSpecificCheck = new SedanSpecificCheck();

    @Override
    public void visit(Mini mini) {
        result = carBasicCheck.hasWorkingBreaks(mini) &&
                miniSpecificCheck.hasDurableSafetyCage(mini);
    }

    @Override
    public void visit(Sedan sedan) {
        result = carBasicCheck.hasWorkingBreaks(sedan) &&
                sedanSpecificCheck.hasEnoughAirbags(sedan);
    }

    public boolean getResult() {
        return result;
    }
}

public class MiniSpecificCheck {

    boolean hasDurableSafetyCage(Mini mini) {
        return mini.getMiniSafetyCageCondition() > 5;
    }

}

public class SedanSpecificCheck {

    public boolean hasEnoughAirbags(Sedan sedan) {
        return sedan.isFrontAirbagsPresent() || sedan.isSideAirbagsPresent();
    }

}

这是示例客户端代码:

public class Client {

    public static void main(String[] args) {

        SafetyVisitor safetyVisitor = new SafetyVisitor();

        Mini safeMini = new Mini(6, 6);
        Mini unsafeMini = new Mini(6, 3);
        Sedan safeSedan = new Sedan(6, true, false);
        Sedan unsafeSedan = new Sedan(6, false, false);

        safetyVisitor.visit(safeMini);
        System.out.println("safeMini is safe: " + safetyVisitor.getResult());
        safetyVisitor.visit(unsafeMini);
        System.out.println("unsafeMini is safe: " + safetyVisitor.getResult());
        safetyVisitor.visit(safeSedan);
        System.out.println("safeSedan is safe: " + safetyVisitor.getResult());
        safetyVisitor.visit(unsafeSedan);
        System.out.println("unsafeSedan is safe: " + safetyVisitor.getResult());
    }

}

这里的优点是您不需要知道正在检查的对象的类型。因此,您可以轻松获得可访问对象的列表,您可以一次性检查所有对象。如果像下面那样简单地检查类,那就不可能了:

public interface CarSaeftyChecker {

    boolean check(Mini mini);

    boolean check(Sedan sedan);

}

答案 3 :(得分:0)

我的设计,

将安全作为一个单独的对象,不同的安全性实现了界面安全。

 
interface Safety
{
    boolean isSafe();
    // Each safety will have its own weightage.
    float   weightage();
}

class AirbagSafety extends Safety
{
    public boolean isSafe()
    {
        // TODO: Your impl goes here.
    }

    public float weightage()
    {
        // A constant
    }
}

 

让汽车有一些标准的安全功能来通过政府法规,

 

class Car
{
    Safety[] standardSafety;  // As prescribed by government.

    public float standardSafetyPoint()
    {
        float safetyPoint;
        for (Safety s : standardSafety) { s.isSafe() ? safetyPoint + weightage(); }
        return safetyPoint;
    }
}

 

让每辆车都有自己的安全点

  

class Sedan extends Car
{
    Safety[] sedanSafety;

    public int safetyPoint()
    {
        float safetyPoint = 0;
        safetyPoint += super.standardSafetyPoint();
        // do a while loop like above and calculate the specific safety point.
        return safetyPoint;
    }
}

 

这样,您可以更好地控制安全性。您可以专门设计继承了很多安全性的宝马安全级别,并将它们放在您的宝马汽车等中。