zoukankan      html  css  js  c++  java
  • 设计模式之二装饰者模式

    一 概述
    1.什么是装饰者模式?
    在不修改类,不使用继承的前提下,用一个对象来装饰另一个对象,以扩展目标对象的功能。

    2.装饰者模式的作用:
    继承也可以扩展类的功能,装饰者模式比继承更加灵活,因为继承时子类受父类的约束,比如子类方法不能降低访问权限,返回值必须是父类方法返回值的子类,而装饰模式就不受这些约束,比较灵活。

    二 基本装饰者模式
    结构:

    • 父类:可以是接口、抽象类、一般类,保证能够以操作目标对象的方式操作装饰者,即保证装饰者拥有与目标对象相同的方法结构。
    • 目标类;
    • 装饰者类:其中包含目标对象引用,往往通过构造器注入。

    三 高级装饰者模式
    1.不仅可以对目标对象进行多种形式的增强,而且可以构建装饰者链将多种增强形式同时施加到目标对象上。

    2.结构

    • 父类。
    • 目标类:实现或者继承了父类。
    • 装饰者基类:实现或继承了父类,只是实现了目标对象方法,并未增强,作为后续增强的基础。
    • 具体装饰者A类:继承了装饰者基类,对目标类进行一种形式的增强。
    • 具体装饰者B类:继承了装饰者基类,对目标类进行一种形式的增强。

    3.按照功能模块化原则,一个模块只负责单一的功能,每一种具体装饰者类,只负责实现一种增强形式。
    4.具体装饰者类对目标类的增强建立在基类处理结果的基础上,因此在代码中通过先super获取基类的结果,然后再进行增强。

    5.构建装饰者链
    ⑴基本原理:

    首先将目标对象传入一个具体装饰者对象中,再将该具体装饰者对象传入下一个具体装饰者对象中,以此推进,形成一个装饰者链,对目标对象逐级增强。
    ⑵构建关键:

    在具体装饰者类中通过super获取基类处理结果,将基类作为中间环节构建装饰者链。

    ⑶实现Demo

    接口

    package com.designmode.decorator.senior;
    
    public interface ISomeService {
    
        String doSome();
    
    }

    目标类

    package com.designmode.decorator.senior;
    
    public class SomeServiceImpl implements ISomeService {
    
        @Override
        public String doSome() {
            return "   abc   ";
        }
    
    }

    装饰者基类

    package com.designmode.decorator.senior;
    
    public class SomeServiceWrapper implements ISomeService {
    
        private ISomeService target;
    
        public SomeServiceWrapper(ISomeService target) {
            super();
            this.target = target;
        }
    
        @Override
        public String doSome() {
            return target.doSome();
        }
    
    }

    具体装饰者A类

    package com.designmode.decorator.senior;
    
    public class TrimDecorator extends SomeServiceWrapper {
    
        public TrimDecorator(ISomeService target) {
            super(target);
            // TODO Auto-generated constructor stub
        }
    
        @Override
        public String doSome() {
            // TODO Auto-generated method stub
            return super.doSome().trim();
        }
    
    }

    具体装饰者B类

    package com.designmode.decorator.senior;
    
    public class UpperDecorator extends SomeServiceWrapper {
    
        public UpperDecorator(ISomeService target) {
            super(target);
            // TODO Auto-generated constructor stub
        }
    
        @Override
        public String doSome() {
            // TODO Auto-generated method stub
            return super.doSome().toUpperCase();
        }
    
    }

    测试类

    package com.designmode.decorator.senior;
    
    import org.junit.Test;
    
    public class DecoratorTest {
    
        /**
         * 装饰者基类,原样实现了目标对象的方法,并未增强
         */
        @Test
        public void test01() {
            ISomeService target = new SomeServiceImpl();
            ISomeService decorator = new SomeServiceWrapper(target);
            String result = decorator.doSome();
            System.out.println("result=" + result);
        }
    
        /**
         * 一次增强,对装饰者基类增强
         */
        @Test
        public void test02() {
            ISomeService target = new SomeServiceImpl();
            ISomeService decorator = new TrimDecorator(target);
            String result = decorator.doSome();
            System.out.println("result=" + result);
        }
    
        /**
         * 形成装饰者链,逐级增强
         */
        @Test
        public void test03() {
            ISomeService target = new SomeServiceImpl();
            ISomeService trimDecorator = new TrimDecorator(target);// 一级增强
            ISomeService service = new UpperDecorator(trimDecorator);// 二级增强
            String result = service.doSome();
            System.out.println("result=" + result);
        }
    
    }

    三 常见装饰者应用
    IO流中广泛使用装饰者模式,一些类正是装饰了基本输入输出流创建的,如XMLWriterDateOutputStreamBufferedInputstream

    ObjectInputstream等。

    四 与静态代理模式对比
    1.相同点:

    • 都与目标类实现共同的接口。
    • 都可以动态地扩展目标类的功能。
    • 都需要在自身类中包含目标对象。

    2.不同点
    ⑴设计目的不同:

    • 装饰者模式是为了增强目标类的功能。
    • 静态代理是为了隐藏与保护目标类。

    ⑵包含目标对象的方式不同:

    • 在装饰者模式中,目标对象由用户创建,通过构造器传入装饰者中,目标对用户可见。
    • 在静态代理模式中,目标对象在装饰者类的无参构造方法中创建,对用户不可见。

    注:静态代理模式请参考http://www.cnblogs.com/tonghun/p/6925614.html

  • 相关阅读:
    使用 requests 维持会话
    使用 requests 发送 POST 请求
    使用 requests 发送 GET 请求
    requests 安装
    使用 urllib 分析 Robots 协议
    使用 urllib 解析 URL 链接
    使用 urllib 处理 HTTP 异常
    使用 urllib 处理 Cookies 信息
    使用 urllib 设置代理服务
    按单生产程序发布
  • 原文地址:https://www.cnblogs.com/tonghun/p/6925547.html
Copyright © 2011-2022 走看看