这是装饰者模式的一个例子。
public class Computer {
public String Description(){
return "Computer";
}
}
public abstract class Decorator extends Computer{
public abstract String description();
}
public class Monitor extends Decorator{
Computer computer;
public Monitor(Computer c){
computer = c;
}
public String description() {
return computer.Description() + " and Monitor";
}
}
public class main {
public static void main(String args[]){
Computer c = new Computer();
Monitor m = new Monitor(c);
System.out.println(m.description());
}
}
调用超类的超级方法是否相同?比如监视器从计算机继承然后调用监视器类中Description方法内的计算机类中的super.Description()?
答案 0 :(得分:5)
通过调用super方法,您需要为每种可能性创建一个新的子类。例如,如果您想要一台带显示器和鼠标的计算机怎么办?您可以创建一个继承Monitor
的子类。现在说你想要一台没有显示器和鼠标的电脑。你也需要另一个子类,它继承了Computer
。只有两个设备,您已经需要三个子类(Monitor
,Mouse
和MonitorAndMouse
)。如果您的计算机还可以配备打印机,扫描仪和一组扬声器怎么办?
使用装饰器模式,您可以使用新设备“装饰”计算机。就像使用Monitor
一样,您可以为每个设备创建不同的装饰器。要创建包含所有设备的计算机,您现在可以执行类似
Computer = new Speakers(
new Scanner(
new Printer(
new Mouse(
new Monitor(
new Computer()
)
)
)
)
);
computer.description();
现在description()
会返回Computer and Monitor and Mouse and Printer and Scanner and Speakers
。您可以将设备与计算机混合搭配,而无需为每个组合创建新的子类。
评论:
在我的例子中,我删除了装饰器类然后监视器没有从计算机类继承,而是我只是将计算机类的实例放在监视器类中,然后执行相同的操作。
这样,您只能进入一级深度,只能将一台设备添加到计算机中。从本质上讲,它是一个不可扩展的装饰器。装饰器模式是favor composition over inheritance的一种方式,因为在添加多个设备时可以获得巨大的增长。使用您的解决方案,您不是通过创建Computer
的子类而是使用Monitor
组成Computer
来支持组合而不是继承。它几乎是一个装饰模式,只有你退后一步。
答案 1 :(得分:1)
简短地回答你的问题:不,它不一样。
装饰器使用现有的对象来修改它的行为,但是对于外部世界来说,它看起来好像是它所装饰的类的典型。
要在您的示例中解释这一点,您有一台计算机,而您的计算机有一些属性。在您的代码中的某个位置,您正在创建此计算机的实例。您正在填写所有需要的数据。
装饰师到位了。你需要一个类来装饰你刚刚创建的计算机实例!正是这个。
我将带你的电脑并添加一个关闭它的方法
public class Computer {
private boolean isOn = true;
private String description = "Computer";
public vod turnOn(){
this.isOn=true;
}
public void turnOff(){
this.isOn = false;
}
public void setDescription(String description){
this.description = description;
}
public String Description(){
return this.description;
}
}
现在我正在创建一个装饰器,你无法关闭电脑。
public class ComputerDecorator1 extends Computer {
private Computer computer;
public ComputerDecorator1(Computer computer){
this.computer = computer;
}
public vod turnOn(){
this.computer.turnOn();
}
public void turnOff(){
System.out.println("You cannot turn me off!!!!");
}
public void setDescription(String description){
this.computer.setDescrition(descritption);
}
public String Description(){
return this.computer.Description();
}
}
如您所见,您必须在构造函数中为他提供一个Computer实例。这是我们正在装修的电脑。每个方法调用都将传递给这个类。 通常,您必须覆盖所有方法并将它们传递给装饰对象。在这种情况下,计算机。
您可以使用它来修改对象的行为,而不用创建它的新类。 好处是,当您从其他地方获得计算机实例时,您可以添加此过滤器,以便您的程序的其余部分无法将其关闭。
这是您在程序中使用装饰器的方法:
public void getMyComputerAndTurnItOff(){
Computer myComputer = getMyComputer();
myComputer.turnOff();
}
public Computer getMyComputer(){
//Here you will load a Computer from an other class
Computer computer = this.otherClass.loadComputerFromDB();
//Now we could return it, but what if you shouldn't be able to turn it off?
//easy add our decorator
return new ComputerDecorator1(computer);
}
如果你想使用装饰器,你需要修改行为,否则它是无用的! 在您从逻辑点使用计算机和监视器的示例中,监视器不能是计算机的装饰器。对我来说,这是两个不同的对象。
我希望我可以让装饰师更清楚一点!