专栏首页栗霖积跬步之旅一天一个设计模式:装饰者模式

一天一个设计模式:装饰者模式

概念:

装饰者模式又称为包装(wrapper)模式。装饰者模式对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。

结构:

装饰者模式以透明的方式给一个对象附加上更多的责任,换而言之,客户端并不会觉得对象在装饰前后有什么不同,装饰者模式可以在不使用创造更多子类的情况下,将对象的功能拓展。

结构图:

角色分析:

抽象构件(Component)角色:给出一个抽象接口,以规范准备接受附加责任的对象。

  具体构件(ConCreteComponent)角色:定义一个将要接受附加责任的类。

  装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。

  具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。

代码:

抽象构建角色:

public interface Component {
    
    public void sampleOperation();
    
}

具体构件角色:

public class ConcreteComponent implements Component {

    @Override
    public 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 ConcreteDecoratorA extends Decorator {

    public ConcreteDecoratorA(Component component) {
        super(component);
    }
    
    @Override
    public void sampleOperation() {
     super.sampleOperation();
        // 写相关的业务代码
    }
}
//B组件类似

具体示例

有工人接口,我们定义了铁匠,现在要对铁匠进行不同的技能强化。

工人接口:

public interface Worker {

    void working();
}

铁匠实现类:

public class Smith implements Worker {

    private String name;

    private int age;

    public Smith(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public void working() {
        System.out.println("我是一个铁匠");
    }
}

技能实现类:

public class Skill implements Worker {
    private Worker worker;

    public Skill(Worker worker) {
        this.worker = worker;
    }

    @Override
    public void working() {
        worker.working();
    }

    //为半透明模式做的拓展
    public void heating(){}
}

具体的技能类1:

public class Hardening extends Skill {
    public Hardening(Worker worker) {
        super(worker);
    }

    @Override
    public void working() {
        System.out.println("我在淬火");
    }
}

具体的技能类2:

public class Beat extends Skill {
    public Beat(Worker worker) {
        super(worker);
    }

    @Override
    public void working() {
        System.out.println("我在反复地捶打");
    }
}

补充:

装饰者模式的简化

1.去掉接口的形式,直接继承自要被装饰的类即可。

2.直接使用实现接口的形式实现装饰,而不用再额外加一层继承关系。适用于只有一个强化关系的情况

透明度的要求:

  装饰者模式要求程序不应该声明需要被装饰的实体类,而是应该声明抽象接口。

用示例中的声明表示就是下面这样:

即所有的人,都是工人,铁匠是工人,会淬火的铁匠也是工人。

        Worker worker1 = new Smith("李铁蛋",18);
        Worker worker2 = new Hardening(worker1);

半透明的装饰模式:

  当发现工人接口并不能满足所有的要求的时候,要想实现透明度要求,必须在接口中添加新方法,所以很多实现的装饰者模式都是采取“半透明”的方式,即装饰者类可以对接口进行拓展,同时声明的时候,可以选择以装饰者类为准。

  本例中,装饰者类就是技能类,我们为淬火技能类添加加热方法

        Worker worker = new Smith("李狗蛋",18);
        Hardening smith = new Hardening(worker);
        smith.heating();

  半透明的装饰者模式是介于装饰者模式跟适配器模式中的,适配器模式的思路是改变接口,也可以通过改写或新增方法实现,大多数装饰者模式实际上都是半透明的装饰者模式。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 一天一个设计模式:策略模式

    策略模式属于对象的行为模式,其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响客户端的情...

    用户1134788
  • 1.3currentThread()方法

    currentThread()方法可以返回段正在被哪个线程调用的信息。 示例代码: public class Main { public static ...

    用户1134788
  • 1.10线程的优先级

    在操作系统中,线程是有优先级划分的,优先级较高的线程会得到相对较多的资源。 也就是说CPU会优先执行优先级较高的线程对象中的任务。 设置线程优先级有助于帮“线程...

    用户1134788
  • java设计模式(15)-观察者模式

    观察者模式很好理解,类似于邮件订阅和RSS订阅,当我们浏览一些博客或wiki时,经常会看到RSS图标,就这的意思是,当你订阅了该文章,如果后续有更新,会及时通知...

    爱敲代码的猫
  • 设计模式-装饰者模式

    用户5927264
  • 常用设计模式全解析

    结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

    技术从心
  • MessagePack Java 0.6.X 可选字段

    https://www.cwiki.us/display/Serialization/QuickStart+For+MessagePack+Java+0.6.X

    HoneyMoose
  • 温故而知新:设计模式之Builder

    Builder模式主要用于以下场景: 需要创建一个较复杂的大对象实例,并且构成该对象的子对象可能经常会发生变化,但是组成大对象的算法却相对稳定。 比如:我们做b...

    菩提树下的杨过
  • 依赖注入容器-- Autofac

    Autofac---Autofac是一款IOC框架,比较于其他的IOC框架,如Spring.NET,Unity,Castle等等所包含的,它很轻量级性能上非常高...

    小世界的野孩子
  • 代理模式

    mySoul

扫码关注云+社区

领取腾讯云代金券