最近复习设计模式,看到这样一个例子。我们要做一个披萨。
Pissa orderPizza(){
Pizza pizza=new Pissa();
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
在new Pizza的时候,Pizza可以由不同类型的子类进行替代。从而重载里面的prepare, bake,cut, box等方法。
这里有一个疑问就是这些操作都可其他对象执行的动作。这又让我想起了英语里面主动形式表示被动。
You look nice. 实际上要表达的是你被看起来不错。但是实际的语言确实主动的。因为这里面要表达的意识是你被任何人看起来都不错,而不是被某个人。被看起来不错强调的是你自己的客观属性,而看的人无关。所以在语言中,不论是逻辑推理还是表达习惯,就渐渐地适应了这种表达方式。
而这里面执行的方法,也都是和现实中主动的对象无关的。pizza被烤,在这个问题里面和烤箱无关,无论什么牌子的烤箱,都要执行我的程序。而这套烧烤的程序是针对pizza指定的,而不同的pizza的流程是不同的,所以要pizza进行方法重写。
如果bake方法是和不同牌子的烤箱相关的,那么可能代码是这个样子。
Oven oven=new GreatOven();
oven.bake(pizza);
但是按照bake的逻辑,bake方法终究要改变的是pizza的属性。那么Oven.bake方法应该是调用了pizza的方法改变其属性,或者直接改变pizza的共有属性。
bake(Pizza pizza){
pizza.setNewColor(yellow);
pizza.setNewTast(sweet);
}
可见终究还是要调用pizza的方法的。
这里我想到了一个哲学问题。或者就是设计模式的问题,就是说一个方法如果被调用,那么他就是可以被替换的,应该要被替换掉。否则没有必要写成一个方法。
回到这个例子里面,就是说既然调用Oven.bake()方法,也就是说不同的Oven对于bake方法应该是有重写的。
比如
Oven oven=new BadOven();
oven.bake(pizza);
这时候一个坏烤箱执行的方法可能是。
bake(Pizza pizza){
pizza.setNewColor(black);
pizza.setNewTast(bitter);
}
不论放进烤箱的pizza是什么,我只要是坏烤箱,就给你黑色和苦味道。我是好的烤箱,就给你黄色和填味道。这是由烤箱决定的方法的不同。
而对于不同的pizza所具有的属性应该在pizza的方法或者属性当中。
比如
Pizza pizza=new SweetPizza();
SweetPizza extends pizza{
……
setNewTast(Tast newTast){
if(newTast==bitter){
this.tast=littleBitter;
}else if(newTast==sweet){
this.tast=verySweet;
}else{
this.tast=sweet;
}
}
}
从上面的代码可以看到,不同的pizza可以它们面对bake的变化在自己的set方法里面体现出来,而这里面表现的是属于pizza的特性。甜pizza即使面对坏烤箱,可不止于太苦。而可是如果苦pizza面对坏烤箱,可能会变得更苦。
综上,我得到了这样一种总结。
一个方法体现的是什么对象属性,并根据不同的该种类对象产生变化,就应该作为那个对象的成员。
而不是按照语言中的理解,把字句或者被字句。把字句和被字句起源于这个词被创造的时候的原始含义。但是他们的用法同样随着要表达的属性的主体而变化。比如说你看着挺精神的。这个水壶很好用。都是体现的是对象的属性。
代码体现的是一种逻辑关系,一种拓展的方向。方法属于哪个对象,方法就会随着这个对象的拓展而拓展。