注册

java 设计模式:装饰者模式

简单详解:

1、概念

动态地给一个对象添加一些额外的职责。就增加功能来说, 装饰模式相比生成子类更为灵活。该模式以对客户端透明的方式扩展对象的功能。

2、使用场景

  1. 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。和继承类似添加相应的职责。
  2. 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

3、UML结构图分析

  • 抽象构件(Component)角色:给出一个抽象接口,已规范准备接收附加责任的对象。
  • 具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类
  • 装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
  • 具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。

4、实际代码分析

/**
* 装饰类Component,所有类的父类
*/
public interface Component {

void sampleOperation();
}

/**
* 实现抽象部件,具体装饰过程还是交给子类实现
*/
public class Decorator implements Component {

private Component component;
public Decorator(Component component){
this.component = component;
}

@Override
public void sampleOperation() {
component.sampleOperation();
}

}

/**
* 需要装扮的类
*/
public class ConcreteComponent implements Component{
@Override
public void sampleOperation() {

}
}

/**
* 具体实现
*/
public class ConcreateDecoratorA extends Decorator{
public ConcreateDecoratorA(Component component) {
super(component);
}

@Override
public void sampleOperation() {
super.sampleOperation();
addPingShengm();
}

/**
* 新增业务方法
*/
private void addPingShengm() {
System.out.println("添加绘彩1");
}
}

/**
* 具体实现
*/
public class ConcreateDecoratorB extends Decorator{
public ConcreateDecoratorB(Component component) {
super(component);
}


@Override
public void sampleOperation() {
super.sampleOperation();
addPingShengm();
}


/**
* 新增业务方法
*/
private void addPingShengm() {
System.out.println("添加绘彩2");
}
}

举一个实际例子:

工厂需要产生多种水杯,有瓶身绘彩,有不锈钢盖被子,也有不锈钢盖和瓶身绘彩的杯子。(等各种需求)

假如说采用继承子类的方式。如下code:

/**
* 创建水杯的接口包含四个方法,底座,盖子,瓶身,一个实现功能product
*/
public interface IShuiBei {

void dizuo();

void gaizi();

void pingsheng();

void product();

}
/**
* 水晶杯实现类
*/
public class ShuiJInBei implements IShuiBei,Component {
@Override
public void dizuo() {
System.out.println("水晶底座");
}

@Override
public void gaizi() {
System.out.println("水晶盖子");
}

@Override
public void pingsheng() {
System.out.println("水晶瓶身");
}

@Override
public void product() {
dizuo();
gaizi();
pingsheng();
}
}

/**
* 添加绘彩的水晶杯
*/
public class HuiCaiShuiJinBei extends ShuiJInBei{
@Override
public void pingsheng() {
super.pingsheng();
System.out.println("添加绘彩");
}
}
/**
* 不锈钢杯子盖的水晶杯
*/
public class HuiJinGangGaiBei extends ShuiJInBei{
@Override
public void gaizi() {
System.out.println("不锈钢杯盖");
}
}

/**
* 不锈钢杯子盖的水晶杯带彩绘
*/
public class HuiCaiShuiJinGangGaiBei extends ShuiJInBei{
@Override
public void gaizi() {
System.out.println("不锈钢杯盖");
}
@Override
public void pingsheng() {
super.pingsheng();
System.out.println("添加绘彩");
}
}

//运行
HuiCaiShuiJinBei huiCaiShuiJinBei = new HuiCaiShuiJinBei();
HuiCaiShuiJinGangGaiBei huiCaiShuiJinGangGaiBei = new HuiCaiShuiJinGangGaiBei();
ShuiJInBei shuiJInBei = new ShuiJInBei();
huiCaiShuiJinBei.product();
huiCaiShuiJinGangGaiBei.product();
shuiJInBei.product();

一共创建三个子类,一个父类,当然如果需求更多的话,子类会不断的增加。

装饰类实现如上功能code:

/**
* 实现抽象部件
*/
public class ShuijinbeiDecorator implements IShuiBei{
IShuiBei iShuiBei;
public ShuijinbeiDecorator(IShuiBei iShuiBei){
this.iShuiBei = iShuiBei;
}

@Override
public void dizuo() {
iShuiBei.dizuo();
}

@Override
public void gaizi() {
iShuiBei.gaizi();
}

@Override
public void pingsheng() {
iShuiBei.pingsheng();
}

@Override
public void product() {
dizuo();
gaizi();
pingsheng();
}
}
/**
* 钢盖实现类
*/
public class GangGaiDecorator extends ShuijinbeiDecorator{
public GangGaiDecorator(IShuiBei iShuiBei) {
super(iShuiBei);
}

@Override
public void gaizi() {
System.out.println("不锈钢杯盖");
}
}

/**
* 彩绘实现类
*/
public class CaihuiDecorator extends ShuijinbeiDecorator{
public CaihuiDecorator(IShuiBei iShuiBei) {
super(iShuiBei);
}

@Override
public void pingsheng() {
super.pingsheng();
System.out.println("添加绘彩");
}
}
//运行
IShuiBei iShuiBei = new ShuiJInBei();
iShuiBei.product();
iShuiBei = new CaihuiDecorator(iShuiBei);
iShuiBei.product();
iShuiBei = new GangGaiDecorator(iShuiBei);
iShuiBei.product();
iShuiBei = new ShuiJInBei();
iShuiBei = new GangGaiDecorator(iShuiBei);
iShuiBei.product();

看到如上代码你大概会恍然大悟,装饰模式如果在你的子类特别多,用装饰模式很好,但是比较容易出错哦。

装饰模式的优点

  1. 装饰模式与继承关系的目的都是要拓展对象的功能,但是装饰模式可以提供比继承更多的灵活性。
  2. 装饰模式允许系统动态决定“贴上”一个需要的“装饰”,或者“除掉”一个不需要的“装饰”。继承关系则不同,继承关系是静态的,它在系统运行前就决定了。
  3. 可以对一个对象进行多次装饰,通过使用不同的具体装饰类以及这些装饰类的排列组合。

装饰模式的缺点

由于使用装饰模式,可以比使用继承关系需要较少数目的类。使用较少的类,当然使设计比较易于进行。但是,在另外一方面,使用装饰模式会产生比使用继承关系所产生的更多的对象。而更多的对象会使得查找错误更为困难,特别是这些对象在看上去极为相似的时候。

装饰模式在Android中的实际应用

context类簇

0 个评论

要回复文章请先登录注册