用接口将继承替换为装饰器模式

时间:2020-07-16 21:00:04

标签: java inheritance design-patterns interface decorator

我正在设计一个带有多个装饰器的类-从而依赖于继承关系。 由于Java中不允许多重继承,因此我尝试找出一种用接口[implements]替换所有继承关系[extends]的方法。

我尝试了几种方法,但都没有解决。尤其是我使用同一装饰器进行多种装饰的方法在我的界面转换中不起作用:

Computer computer = new Computer();

computer = new Loudspeaker(new Loudspeaker(computer));
System.out.println("My system with " + computer.buy() );

这种图案的孔洞方法是围绕用两个扬声器进行装饰而设计的。

这将导致打印输出: 我的带有计算机,扬声器和扬声器的系统

您是否有建议摆脱尽可能多的继承?我的孔代码:

protected class Computer {

protected String buy() {
    return "a computer";
} }


public class Loudspeaker extends Decorator {

Computer computer;

public Loudspeaker(Computer c) {
    computer = c;
}

@Override
public String buy() {
    return computer.buy() + " and a loudspeaker";
}}


public abstract class Decorator extends Computer {
    protected abstract String buy();
}

1 个答案:

答案 0 :(得分:1)

您需要考虑多个方面。首先是计算机销售的模型。但是仅以您的示例为例,下面的内容将帮助您开始工作。还有更多优化的可能...

import java.util.ArrayList;
import java.util.List;

public class CompositionEx {
    public static void main(String[] args) {
        Computer computer = new Computer(100.00);
        LoudSpeaker loudSpeaker = new LoudSpeaker(20.50);
        computer.addPeripheral(loudSpeaker);
        computer.addPeripheral(loudSpeaker);
        System.out.println(computer.getPrice());
    }
}

class Computer implements Sellable {
    private final List<Peripheral> peripherals = new ArrayList<>();
    private final double basePrice;

    public Computer(double basePrice) {
        this.basePrice = basePrice;
    }

    boolean addPeripheral(Peripheral device) {
        return peripherals.add(device);
    }

    @Override
    public double getPrice() {
        return basePrice + peripherals.stream().mapToDouble(Sellable::getPrice).sum();
    }
}

class LoudSpeaker implements Peripheral {
    private double price;

    public LoudSpeaker(double price) {
        this.price = price;
    }

    @Override
    public double getPrice() {
        return price;
    }
}

interface Peripheral extends Sellable {
}

interface Sellable {
    double getPrice();
}