Java - 添加方法的访问者模式
Java - Visitor pattern for adding methods
所以我为液体创建了一个简单的访客模式。如牛奶、果汁和白酒。
牛奶 class 可以是这样的:
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);
和 "visitor" 会为我计算每种液体的税收。当我想添加新计算时,我看到了不必修改对象集合本身的好处。但是当我想添加一个新方法时,我的麻烦就来了。例如,遵循开放封闭原则,我不应该向牛奶 class 添加新方法。但是让我们想象一下,我想添加功能来了解液体的颜色。所以我想扩展 milk 对象以拥有一个名为 "getColor()" 的方法,该方法将 return“#FFFFFF”。如果我想遵循 SOLID 开闭原则,这似乎我需要一个装饰器模式来添加此功能。有没有办法用访客模式做到这一点?
添加函数,你没有违反O/C
添加新函数不会违反 O/C,只要该函数不影响任何现有代码即可。在液体中添加 getColor()
就完全没问题了。
O/C 是关于防止修改 现有 代码
O/C的目的是为了避免违约。当开发人员编写软件时,他们会准确指定软件应该如何工作和不应该如何工作。这是合同。
在编写其他开发人员所依赖的代码时,您无法确定这些开发人员制定了哪些合同。您所知道的只是您为代码定义的合同。开发人员相信您不会以修改他们合同的方式修改您的合同。
由于您无法确定更改您的合约是否会影响其他开发者的合约,因此其他开发者使用您的任何代码必须是“CLOSED 以进行修改”,否则您将面临违反合同的风险。
O/C 不会阻止您扩大规模
添加对现有代码没有影响的代码不会带来干扰其他开发者合同的风险。
如果你增加一些功能,没有人会强迫客户在他们的系统中使用这些新功能;如果不使用它们,则无需担心任何潜在风险,甚至无需担心它们的工作方式。 类 是“OPEN for extension”,因为它不会对现有客户造成任何潜在伤害。
所以我为液体创建了一个简单的访客模式。如牛奶、果汁和白酒。
牛奶 class 可以是这样的:
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);
和 "visitor" 会为我计算每种液体的税收。当我想添加新计算时,我看到了不必修改对象集合本身的好处。但是当我想添加一个新方法时,我的麻烦就来了。例如,遵循开放封闭原则,我不应该向牛奶 class 添加新方法。但是让我们想象一下,我想添加功能来了解液体的颜色。所以我想扩展 milk 对象以拥有一个名为 "getColor()" 的方法,该方法将 return“#FFFFFF”。如果我想遵循 SOLID 开闭原则,这似乎我需要一个装饰器模式来添加此功能。有没有办法用访客模式做到这一点?
添加函数,你没有违反O/C
添加新函数不会违反 O/C,只要该函数不影响任何现有代码即可。在液体中添加 getColor()
就完全没问题了。
O/C 是关于防止修改 现有 代码
O/C的目的是为了避免违约。当开发人员编写软件时,他们会准确指定软件应该如何工作和不应该如何工作。这是合同。
在编写其他开发人员所依赖的代码时,您无法确定这些开发人员制定了哪些合同。您所知道的只是您为代码定义的合同。开发人员相信您不会以修改他们合同的方式修改您的合同。
由于您无法确定更改您的合约是否会影响其他开发者的合约,因此其他开发者使用您的任何代码必须是“CLOSED 以进行修改”,否则您将面临违反合同的风险。
O/C 不会阻止您扩大规模
添加对现有代码没有影响的代码不会带来干扰其他开发者合同的风险。
如果你增加一些功能,没有人会强迫客户在他们的系统中使用这些新功能;如果不使用它们,则无需担心任何潜在风险,甚至无需担心它们的工作方式。 类 是“OPEN for extension”,因为它不会对现有客户造成任何潜在伤害。