2

这是装饰器模式的一个例子。

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()?

4

2 回答 2

5

通过调用 super 方法,您需要为每种可能性创建一个新的子类。例如,如果您想要一台带显示器和鼠标的计算机怎么办?您可以创建一个继承的子类Monitor。现在假设您想要一台没有显示器和鼠标的计算机。您还需要另一个子类,它继承Computer. 只有两个设备,您已经需要三个子类(MonitorMouseMonitorAndMouse。如果您的计算机也可以配备打印机、扫描仪和一组扬声器怎么办?

使用装饰器模式,您可以用新设备“装饰”计算机。就像您对 所做的一样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。您可以将设备与计算机混合搭配,而无需为每个组合创建新的子类。

评论:

在我的示例中如何删除装饰器类然后监视器没有从计算机类继承,而是我只是将计算机类的实例放在监视器类中然后做同样的事情。

这样,您只能深入一层,您只能将一个设备添加到计算机。本质上,它是一个不可扩展的装饰器。装饰器模式是一种支持组合而不是继承的方式,因为在添加多个设备时会获得巨大的可能性。使用您的解决方案,您倾向于组合而不是继承,方法是不创建 the 的子类,Computer而是Monitor使用Computer. 它几乎是一个装饰器模式,只是你退了一步。

于 2012-04-04T07:43:30.357 回答
1

简而言之,回答您的问题:不,不一样。

Decorator 使用现有的 Object 来修改它的行为,但对于外部世界来说,它看起来好像它装饰的类的一个类型。

为了在您的示例中解释这一点,您有一台计算机,并且您的计算机具有一些属性。在您的代码中的某处,您正在创建这台计算机的一个实例。您正在用所有需要的数据填充它。

现在装饰器就位了。您需要一个类来装饰您刚刚创建的计算机的这个实例!正是这个。

我会拿你的电脑并添加一个方法来关闭和打开它

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);
}

如果要使用装饰器,则需要修改行为,否则无用!在您的计算机和监视器示例中,从逻辑角度来看,监视器不能成为计算机的装饰器。对我来说,这是两个不同的对象。

我希望我能让装饰器更清楚一点!

于 2012-04-04T08:16:55.850 回答