我的设计模式系列项目地址:
GitHub - GodisGod/DesignPatternStudy: 设计模式学习demo
https://github.com/GodisGod/DesignPatternStudy
介绍:
装饰模式也称为包装模式,结构型设计模式之一。
基本框架:
1、需要一个抽象方法类
2、需要一个抽象装饰器类
3、创建装饰器
代码示例:
1、创建抽象方法类和具体实现类
/**
* 抽象方法类
*/
public abstract class Component {
/**
* 抽象方法
*/
public abstract void operate();
}
/**
* 未经装饰的组件实现类
*/
public class ConcreteComponent extends Component {
@Override
public void operate() {
//具体逻辑
Log.i("LHD", "组件具体逻辑");
}
}
2、然后创建抽象装饰器类和具体装饰器类
/**
* 装饰器抽象类
*/
public class Decorator extends Component {
private Component component;//持有一个Component对象的引用
/**
* 将Component对象传给装饰器
*
* @param component
*/
public Decorator(Component component) {
this.component = component;
}
@Override
public void operate() {
//调用组件的具体方法
component.operate();
}
}
/**
* 具体装饰器A
*/
public class RealDecoratorA extends Decorator {
/**
* 将Component对象传给装饰器
*
* @param component
*/
public RealDecoratorA(Component component) {
super(component);
}
@Override
public void operate() {
operate1();//装饰方法可以在父类方法之前调用也可以在之后调用
super.operate();//调用具体的组件方法
operate2();
}
/**
* 装饰方法1
*/
private void operate1() {
Log.i("LHD", "A装饰器1");
}
/**
* 装饰方法2
*/
private void operate2() {
Log.i("LHD", "A装饰器2");
}
}
/**
* 具体装饰器B
*/
public class RealDecoratorB extends Decorator {
/**
* 将Component对象传给装饰器
*
* @param component
*/
public RealDecoratorB(Component component) {
super(component);
}
@Override
public void operate() {
operate1();//装饰方法可以在父类方法之前调用也可以在之后调用
super.operate();
operate2();
}
/**
* 装饰方法1
*/
private void operate1() {
Log.i("LHD","B装饰器1");
}
/**
* 装饰方法2
*/
private void operate2() {
Log.i("LHD","B装饰器2");
}
}
3、我们创建了两个装饰器A和B,接下来我们使用装饰器装饰组件
//构造需要被装饰的组件对象
Component component = new ConcreteComponent();
//构造装饰器A,调用装饰器A的方法装饰组件对象
RealDecoratorA realDecoratorA = new RealDecoratorA(component);
realDecoratorA.operate();
//构造装饰器B,调用装饰器B的方法装饰组件对象
RealDecoratorB realDecoratorB = new RealDecoratorB(component);
realDecoratorB.operate();
查看输出:
可以看到装饰器的原理就是把要装饰的对象传给装饰器,然后装饰器内部调用一些装饰方法。如果装饰器需要操作Component对象,只需要将装饰器抽象类的private Component component;改为public Component component;即可。此处不再示例。
然后我们看一个具体的装饰器的使用例子:
汽车工厂生产汽车,宝马和法拉利的生产流程并不相同,我们用装饰器模式实现这个场景。
1、创建生产汽车的抽象类和生产汽车的实现类
/**
* 抽象方法类
*/
public abstract class Component {
/**
* 抽象方法
*/
public abstract void operate();
}
/**
* 未经装饰的汽车工厂
*/
public class CarFactory extends Component {
@Override
public void operate() {
Log.i("LHD", "安装汽车发动机");
}
}
2、创建抽象车厂装饰类和具体的宝马车厂和法拉利车厂
/**
* 抽象车厂装饰类
*/
public class FactoryDecorator extends Component{
//保持一个基本组件的引用
protected Component component;
public FactoryDecorator(Component component) {
this.component = component;
}
@Override
public void operate() {
//调用基本组件的方法
component.operate();
}
}
/**
* 宝马车汽车厂
*/
public class BMW extends FactoryDecorator {
public BMW(Component component) {
super(component);
}
@Override
public void operate() {
installCarTyre();//安装车标
super.operate();//安装发动机
installCarLogo();//安装汽车logo
}
/**
* 安装车标
*/
private void installCarLogo() {
Log.i("LHD", "安装宝马车标");
}
/**
* 安装轮胎
*/
private void installCarTyre() {
Log.i("LHD", "安装宝马车轮胎");
}
}
/**
* 法拉利装饰器
*/
public class Ferrari extends FactoryDecorator{
public Ferrari(Component component) {
super(component);
}
@Override
public void operate() {
super.operate();//安装发动机
installCarLogo();//安装汽车logo
installCarTyre();//安装车标
}
/**
* 安装车标
*/
private void installCarLogo() {
Log.i("LHD", "安装法拉利车标");
}
/**
* 安装轮胎
*/
private void installCarTyre() {
Log.i("LHD", "安装法拉利轮胎");
}
}
好啦!接下来我们就可以生产汽车啦 (^ ▽ ^)
//安装上汽车发动机了
CarFactory carFactory = new CarFactory();
//让宝马车厂加工
BMW bmw = new BMW(carFactory);
bmw.operate();
//或者让法拉利车厂加工
Log.i("LHD","--------------法拉利车厂--------------");
Ferrari ferrari = new Ferrari(carFactory);
ferrari.operate();
运行输出:
可以看到输出和我们预先设计的一样呢,以上就是装饰模式的简单介绍啦! (^ ▽ ^)