所以我创建了一个简单的液体访客模式。如牛奶,果汁和白酒。
Milk类可以是这样的:
public class Milk implements Visitable{
public float tax=0;
@Override
public int price() {
return 4;
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
//同样适用于果汁和酒
然后我们可以让一个看起来像这样的访客来计算税收的工作:
public class TaxVisitor implements Visitor {
double taxPerentLiquor=.18;
double taxPerentMilk=.15;
double taxPerentJuice=.10;
@Override
public void visit(Liquor liquor) {
int price =liquor.price();
liquor.setTax((float) (price*taxPerentLiquor));
}
@Override
public void visit(Milk milk) {
float price =milk.price();
milk.setTax((float) (price*taxPerentMilk));
}
@Override
public void visit(Juice juice) {
int price =juice.price();
juice.setTax((float) (price*taxPerentJuice));
}
}
当我们使用它时,我们会这样做:
Visitor taxVisitor = new TaxVisitor();
Milk milk = new Milk();
Juice juice = new Juice();
milk.accept(taxVisitor);
juice.accept(taxVisitor);
和"访客"会为我计算每种液体的税。当我想添加一个新的计算时,我看到了我没有必要修改对象集合的好处。但是当我想添加一种新方法时,我遇到了麻烦。遵循开放式封闭原则,我不应该为牛奶类添加新方法。但让我们想象一下,我想添加功能来了解液体的颜色。所以我想扩展牛奶对象以获得一个名为" getColor()"的方法。这将返回" #FFFFF"。这似乎我需要一个装饰模式来添加此功能,如果我想遵循SOLID开放封闭原则。有没有办法用访客模式做到这一点?
答案 0 :(得分:3)
只要该功能不影响任何现有代码,您就不会通过添加新功能来违反O / C.将getColor()
添加到您的液体中完全没问题。
O / C的目的是避免违反合同。当开发人员编写软件时,他们将准确指定软件应该和不应该工作的方式。这是合同。
在编写其他开发人员所依赖的代码时,您无法确定这些开发人员已设置的合同。您所知道的就是您为代码定义的合同。开发人员相信您不会以修改合同的方式修改合同。
由于您无法确定更改合同是否会影响其他开发人员的合同,因此其他开发人员使用的任何代码必须为“ 已关闭 才能进行修改“,或者您违反合同的风险。
添加对现有代码没有影响的代码不会带来干扰其他开发者合同的风险。
如果你添加一些功能,没有人强迫客户在他们的系统中使用这些新功能;如果它们不在使用中,它们不需要担心任何潜在的风险,或者它们如何工作。类“ OPEN for extension ”,因为它不会对现有客户造成任何潜在的伤害。