羿先生的学习笔记[7]:Decorator设计模式

羿先生的学习笔记[7]: Decorator设计模式

假设我们经营着一家坦克工厂。我们已经实现了一个坦克的接口Tank:

public interface Tank {
    public void drive();
    public void fire();
}

和实现了坦克接口的抽象类:

public abstract class AbstractTank implements Tank {
    protected String type;
    
    @Override
    public void drive() {
        System.out.println(type + " moving forward!");
    }

    @Override
    public void fire() {
        System.out.println(type + " main gun open fire!");
    }

    @Override
    public String toString() {
        return type + "\n" + "main gun";
    }
}

以及两种具体的坦克:59和谢尔曼

public class Tank59 extends AbstractTank{
    public Tank59() {
        type = "59式";
    }
}

public class Sherman extends AbstractTank {
    public Sherman() {
        type = "Sherman";
    }
}

现在我们的坦克工厂开工了。
我们的坦克目前只有一门主炮,客户希望能在我们的坦克上加装雷达与机枪。如果我们在每类坦克的代码中都进行修改,那么我们坦克类型越多,就会有越大的、高度重复的工作量。我们对此的解决方法就是使用Decorator设计模式。Decorator设计模式本质上是给已有的类进行打包并加入新的具体特性。
为了给我们的坦克加上机枪和雷达,我们首先用一个TankDecorator抽象类实现Tank接口:

public abstract class TankDecorator implements Tank{
    protected Tank tank;
}

并分别使用两个具体的分别表示机枪和雷达的装饰类去实现:

public class TankWithMachineGun extends TankDecorator{
    public TankWithMachineGun(Tank tank){
        this.tank = tank;
    }

    @Override
    public void drive() {
        tank.drive();
    }

    @Override
    public void fire() {
        tank.fire();
        System.out.println("Machine gun open fire!");
    }

    @Override
    public String toString() {
        return tank.toString() + "\n" + "machine gun";
    }
}

public class TankWithRadar extends TankDecorator{
    public TankWithRadar(Tank tank){
        this.tank = tank;
    }

    @Override
    public void drive() {
        tank.drive();
        System.out.println("Radar is detecting enemy.");
    }

    @Override
    public void fire() {
        tank.fire();
    }

    @Override
    public String toString() {
        return tank.toString() + "\n" + "radar";
    }
}

以机枪为例,TankWithMachineGun类实质是把一个坦克对象包装起来,调用fire()方法时先调用包装的坦克的fire方法再执行机枪开火的代码。
现在我们生产一辆安装有雷达和机枪的59坦克并进行一些测试:

public class Test {
    public static void main(String[] args) {
        Tank tank59 = new Tank59();
        Tank tank59_1 = new TankWithMachineGun(tank59);//59改-1
        Tank tank59_2 = new TankWithRadar(tank59_1);//59改-2
        System.out.println(tank59_2);//打印参数
        tank59_2.drive();//移动测试
        tank59_2.fire();//射击测试
    }
}

输出:

59式
main gun
machine gun
radar
59式 moving forward!
Radar is detecting enemy.
59式 main gun open fire!
Machine gun open fire!

可见我们已经成功地完成了组装。
以下是Decorator模式结构的一个图解:
在这里插入图片描述
Decorator模式的特点在于:

  • 可以很容易的重复添加一个特性
  • 可以递归的嵌套多个装饰
  • 对客户透明,客户不知道某个具体组件有没有被装饰
  • 符合开发-闭合原则:通过新增具体组件和具体装饰者来达到扩展的目的

Decorator模式可以在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。当用过直接继承会产生过多的子类时,我们最好采用Decorator模式。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值