zoukankan      html  css  js  c++  java
  • 装饰器模式

    转载:http://blog.51cto.com/liukang/2046423

    属于结构型模式,它是作为现有的类的一个包装,是继承关系的一个替代方案。

    Java I/O的设计就是采用了装饰者模式,各种InputStreamOutputStream层层嵌套,感觉就像洋葱,如果给装饰者一个形象化的吉祥物,想必非洋葱莫属。

    eg:

    //装饰器或者被装饰对象者统一实现接口或抽象类
    public abstract class Display {
            public abstract int getColumn();
            public abstract int getRows();
            public abstract String getRowText(int row);
            public final void show() {
                    for (int i = 0; i < getRows(); i++) {
                            System.out.println(getRowText(i));
                    }
            }
    }

    //被装饰对象
    public class StringDisplay extends Display {
        private String string;
    
        public StringDisplay(String string) {
            this.string = string;
        }
    
        public int getColumn() {
            return string.getBytes().length;
        }
    
        public int getRows() {
            return 1;
        }
    
        public String getRowText(int row) {
            if (row == 0) {
                return string;
            } else {
                return null;
            }
        }
    }
    //装饰器模式的关键:
    //
    一个装饰者的抽象类,被所有装饰者继承,实现被装饰对象相同的接口(表明装饰者也可以被装饰),并聚合该接口(表面可以接收其他装饰对象),保留装饰积累,层层增强。 //可以有,也可以没有 public abstract class BoardStringDisplay extends Display { protected Display display; protected BoardStringDisplay(Display display) { this.display = display; } }
    //某一个装饰者,装饰者装饰别人的时候,也被别人装饰
    public class SideBoardStringDisplay extends BoardStringDisplay {
    
        protected SideBoardStringDisplay(Display display) {
            super(display);
        }
    
        public int getColumns() {
        //使用父类display成员对象 代理的体现:
    return 1 + display.getColumns() + 1; // 文字两侧各增加一个字符 } public int getRows() { return display.getRows(); // 行数不变 } public String getRowText(int row) { return "|" + display.getRowText(row) + "|"; } }
    //某一个装饰者
    public class FullBoardStringDisplay extends BoardStringDisplay {
    
        protected FullBoardStringDisplay(Display display) {
            super(display);
        }
    
        public int getColumns() {
            return 1 + display.getColumns() + 1;
        }
    
        public int getRows() {
            return 1 + display.getRows() + 1;
        }
    
        public String getRowText(int row) {
            if (row == 0 || row == display.getRows() + 1) {
                return "+" + makeLine('-', display.getColumns()) + "+";
            } else  {
                return "|" + display.getRowText(row - 1) + "|";
            }
        }
    
        private String makeLine(char ch, int count) {
            StringBuffer buf = new StringBuffer();
            for (int i = 0; i < count; i++) {
                buf.append(ch);
            }
            return buf.toString();
        }
    }

    最终测试:样凑效果:

    public class Client {
        public static void main(String[] args) {
            Display d1 = new StringDisplay("Hello, world!");
            Display d2 = new SideBoardStringDisplay(d1);
         //模拟IO流,层层装饰 Display d3
    = new FullBoardStringDisplay( new SideBoardStringDisplay( new FullBoardStringDisplay(d2))); System.out.println("显示字符串>>>>>>"); d1.show(); System.out.println(" 增加两侧边框>>>>>>"); d2.show(); System.out.println(" 再增加全边框、两侧边框、全边框>>>>>>"); d3.show(); } }
    //
    |Hello, world!|
    装饰后:
    +-------------+
    |Hello, world!|
    +-------------+
    装饰后:
    +---------------+
    |+-------------+|
    ||Hello, world!||
    |+-------------+|
    +---------------+
     
    
    

     StringDisplay是被装饰者,SideBoardStringDisplayFullBoardStringDisplay是装饰器,同时也能够被装饰,因为说到底,它们都是继承自Display,所以可以层层嵌套,不断增强。


    装饰器模式的特点:

    1. 接口透明,在不改变被装饰者的前提下增加功能。无论是装饰器还是被装饰者,都有共同的抽象,也许是继承同一个抽象类,也许是实现同一个接口;如此一来,装饰前后的对象都是对外提供同样的服务。就像生日蛋糕(抽象父类或接口),无论是装饰了草莓、还是慕斯、还是巧克力,都还是蛋糕(不改变被装饰者是蛋糕的事实),不会变成一块披萨。
    2. 使用了委托(代理)。装饰器将被装饰的对象(可能会是另一个装饰器实例)作为成员,使得类之间称为弱关联关系,这一点和桥接模式(出发地聚合桥接口,目的地实现桥接口,两侧互不影响)的出发点是一致的。此模式与代理模式有些类似,主要区别在于应用场景和目的,装饰器模式应当为所装饰的对象提供增强功能,而代理模式对被代理的对象施加控制,并不提供对对象本身的增强。

  • 相关阅读:
    js画矩形
    js加载pdf截屏生成图片调用ocr识别成文字
    C#List或者Set集合相同的key合并Value的值
    Oracle学习笔记读懂执行计划(十八)
    Java 阻塞队列
    SpringMVC(三):参数绑定、输入输出转换
    springMVC(二): @RequestBody @ResponseBody 注解实现分析
    Spring Security 4.2.3 Filters 解析
    MySQL 加锁处理分析
    Innodb semi-consistent 简介
  • 原文地址:https://www.cnblogs.com/brxHqs/p/9578035.html
Copyright © 2011-2022 走看看