首先,假设项目有个核心功能。
随着项目迭代,又产生功能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 {@Overridepublic void show() {this.run();}@Overridepublic 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();}@Overridepublic void run() {}
}
public class SwinDecorator extends ICarDecoeator {public SwinDecorator(ICar icar) {super(icar);}public void swin() {System.out.println("可以潜水");}@Overridepublic void run() {}@Overridepublic void show() {this.getIcar().show();this.swin();}
}
public class JumpDecorator extends ICarDecoeator {public JumpDecorator(ICar iCar){super(iCar);}@Overridepublic void show() {this.getIcar().show();this.jump();}public void jump(){System.out.println("车可以跳");}@Overridepublic 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();//跑,游,飞,跳}
}