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


    概念:

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

    结构:

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

    结构图:

    角色分析:

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

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

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

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

    代码:

    抽象构建角色:

    public interface Component {
        
        public void sampleOperation();
        
    }
    View Code

    具体构件角色:

    public class ConcreteComponent implements Component {
    
        @Override
        public void sampleOperation() {
            // 写相关的业务代码
        }
    
    }
    View Code

    装饰者角色:

    public class Decorator implements Component{
        private Component component;
        
        public Decorator(Component component){
            this.component = component;
        }
    
        @Override
        public void sampleOperation() {
            // 委派给构件
            component.sampleOperation();
        }
        
    }
    View Code

    具体装饰者角色:

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

    具体示例

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

    工人接口:

    public interface Worker {
    
        void working();
    }
    View Code

    铁匠实现类:

    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("我是一个铁匠");
        }
    }
    View Code

    技能实现类:

    public class Skill implements Worker {
        private Worker worker;
    
        public Skill(Worker worker) {
            this.worker = worker;
        }
    
        @Override
        public void working() {
            worker.working();
        }
    
        //为半透明模式做的拓展
        public void heating(){}
    }
    View Code

    具体的技能类1:

    public class Hardening extends Skill {
        public Hardening(Worker worker) {
            super(worker);
        }
    
        @Override
        public void working() {
            System.out.println("我在淬火");
        }
    }
    View Code

    具体的技能类2:

    public class Beat extends Skill {
        public Beat(Worker worker) {
            super(worker);
        }
    
        @Override
        public void working() {
            System.out.println("我在反复地捶打");
        }
    }
    View Code

    补充:

    装饰者模式的简化

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

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

    透明度的要求:

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

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

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

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

    半透明的装饰模式:

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

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

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

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

      

  • 相关阅读:
    程序员副业那些事:聊聊出书和录视频
    跳槽时,不敢要高工资也会对候选人不利
    SQL 查询今天、昨天、7天内、30天的数据
    jquery table按列名称排序
    Asp.Net微信js分享
    表格插件BootStrap-Table使用教程
    ASP.NET中IOC容器Autofac(依赖注入DI 控制反转IOC)
    IIS添加MIME类型.woff/.svg/.woff2/.eot/.otf.ttf
    div垂直居中水平居中css
    Asp.Net报https请求报传输流收到意外的 EOF 或 0 个字节
  • 原文地址:https://www.cnblogs.com/lilinzhiyu/p/9916234.html
Copyright © 2020-2023  润新知