[设计模式] ------ 装饰模式

本文介绍了一种使用装饰模式为已有核心功能动态增加其他功能的方法。通过一个具体的汽车功能装饰案例,详细展示了装饰模式的设计与实现过程。

首先,假设项目有个核心功能。
随着项目迭代,又产生功能1和功能2
于是有如下需求:
某个场景需要核心功能和功能1组合,
某个场景需要核心功能和功能2组合,
某个场景需要核心功能和功能1和功能2组合,
甚至以后有了功能3,某个场景要核心功能和功能1和功能3组合。

那么这种情况,就要使用装饰模式,为已有核心功能按一定顺序动态增加其他功能。
使用装饰模式,优点在于区分核心功能和其他装饰功能。而且按照装饰模式的套路写,可以将功能的组装看成一条链,一个个的将各个功能动态的穿起来。

具体实现

下面举个例子:
比如一辆车,核心功能就是跑起来。
同时我们再为车装饰一些牛逼的其他功能,
比如功能1就是飞起来,
功能2就是游泳
功能3就是跳起来

接下来我们使用装饰模式,来将这些功能一个个的装饰在这辆车上。
(也可以先看后面代码,照着代码再看下面的步骤)

第一步:

我们需先定义一个接口ICar,有两个方法,一个是show,一个是run
show方法,就是用于以后多个装饰器之间的连接,run方法就是核心的跑方法。

第二步:

定义一个类RunICar,实现接口ICar,这就是辆真正的车了。
重写run方法,里面就是具体的核心实现。
重写show方法,里面只做一件事,就是调用run方法。
至此,一个初期的车就做出来了。

第三步:

定义一个抽象类ICarDecoeator,实现接口ICar,这个抽象类就是我们所说的装饰类的抽象类。
抽象类中定义一个成员变量ICar,引用是个接口,具体是哪个实现类,就看传哪个实现类了,也是为了后续调用ICar的方法,就直接调到传的那个实现类中了。
再定义一个有参构造方法,入参就是接口ICar,实现就是将入参赋给类中的成员变量ICar。

第四步:

这下就是真正的装逼功能的实现了。
定义类FlyDecorator,继承第三步中的抽象类ICarDecoeator
定义有参构造方法,传入ICar,并传给父类,即super(iCar),
定义本类的装饰功能,比如创建方法fly(),具体实现就是飞起来
同时重写run方法和show方法。
run方法可以为空
重点是show方法,这可是装饰模式的精髓所在。
show方法有两步,第一步是获取ICar引用,并调用iCar的show方法,这样就相当于传进来的ICar的调用,也就是这一步,才让装饰模式真正的链起来了。
show的第二部,是调用自己特有的方法,fly()。

第五步

同第四步,再定义实现类SwinDecorator,继承ICarDecoeator
定义有参构造方法,传入ICar,并传给父类,即super(iCar),
定义本类的装饰功能,比如创建方法swin(),具体实现就是游泳
同时重写run方法和show方法。
run方法可以为空
show也是先获取父类成员变量ICar,并调用show方法。再调用自己的方法swin()

第六步

同第四步,再定义实现类JumpDecorator,继承ICarDecoeator
定义有参构造方法,传入ICar,并传给父类,即super(iCar),
定义本类的装饰功能,比如创建方法jump(),具体实现就是跳起来
同时重写run方法和show方法。
run方法可以为空
show也是先获取父类成员变量ICar,并调用show方法。再调用自己的方法jump()

第七步

第四五六步,都是装饰的附加功能,至此,所有准备工作就完了
第七步来测试下。
先来个核心功能RunICar,车就能跑了。
如果再想实现飞的功能,就new一个FlyDecorator,并将RunICar传入FlyDecorator的有参构造,调用show方法即可。
如果不但想跑,想飞,还想游泳,就再new一个SwinDecorator,并将FlyDecorator传入SwinDecorator的有参构造,调用show方法即可。
如果不但想跑,想飞,想游泳,还想跳,就再new一个JumpDecorator,并将之前能跑能飞能游泳的SwinDecorator传入JumpDecorator的有参构造,调用show方法即可。

接下来是代码示例:

public interface ICar {

    public void show();

    public void run();

}
public class RunICar implements ICar {
    @Override
    public void show() {
        this.run();
    }
    @Override
    public void run() {
    	//核心功能实现
        System.out.println("车辆可以跑");
    }
}
public abstract class ICarDecoeator implements ICar {
    //2.抽象装饰类包含抽象组件的一个引用。作用:装饰类给传递进来的组件添加新的功能
    private ICar icar;

    //有参构造方法用于获取组件
    public ICarDecoeator(ICar icar) {
        super();
        this.icar = icar;
    }
    public ICar getIcar() {
        return icar;
    }

    public void setIcar(ICar icar) {
        this.icar = icar;
    }
}
public class FlyDecorator extends ICarDecoeator {

    public FlyDecorator(ICar icar) {
        super(icar);
    }

    public void fly() {
        System.out.println("车辆可以飞");
    }

    public void show() {
        this.getIcar().show();
        this.fly();
    }

    @Override
    public void run() {

    }
}
public class SwinDecorator extends ICarDecoeator {

    public SwinDecorator(ICar icar) {
        super(icar);
    }

    public void swin() {
        System.out.println("可以潜水");
    }

    @Override
    public void run() {

    }

    @Override
    public void show() {
        this.getIcar().show();
        this.swin();
    }
}
public class JumpDecorator extends ICarDecoeator {

    public JumpDecorator(ICar iCar){
        super(iCar);
    }

    @Override
    public void show() {
        this.getIcar().show();
        this.jump();
    }
    public void jump(){
        System.out.println("车可以跳");
    }

    @Override
    public void run() {

    }
}

public class DecoratorMain {

    public static void main(String[] args) {
        /**使用装饰模式,给具体组件添加功能。在用户需要什么功能,就将具体组件作为参数传递为具体装饰类。
         客户端在调用时,是以透明的方式扩展对象功能,是继承关系的一种替换。

         */
        ICar icar = new RunICar();

        ICar flyicar = new FlyDecorator(icar);
        flyicar.show();//跑,飞
        System.out.println("------------");

        ICar swinicar = new SwinDecorator(icar);
        swinicar.show();//跑,游

        System.out.println("-----------");

        ICar swin = new SwinDecorator(flyicar);
        swin.show();//跑,飞,游

        System.out.println("-----------");

        ICar flyDecorator = new FlyDecorator(swinicar);
        flyDecorator.show();//跑,游,飞

        System.out.println("------------");
        ICar jumpDecorator = new JumpDecorator(flyDecorator);
        jumpDecorator.show();//跑,游,飞,跳

    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值