• 设计模式4:装饰模式(1)


      作用:

      基于已经存在的功能提供增强功能。

      将扩展的类作为新的类的构造函数参数传入,然后对这个类进行装饰处理。

      为了让装饰者有被装饰的功能,需要存在继承关系。

      简单的点讲就是为了扩展一个已定义好的类的功能,而不修改原来类的定义,原来的类仍然可以继续使用,现在定义一个新的类继承原来的类,同时在这个新的类中定义父类的成员变量,同时在构造方法中将外界的一个父类对象传给这个成员变量,然后既可以通过这个成员变量使用父类的方法,同时又可以增加新的方法实现对父类功能的扩充。例如IO流中很多类都采用了装饰模式,如BufferedReader类是装饰了Reader类,LineNumberReader类装饰了BufferedReader类。

      示例1:

     1 package com.qianfeng.decorator;
     2 
     3 public class Demo12 {
     4 
     5     public static void main(String[] args) {
     6         Person p1 = new Zhansan();
     7         p1.show();
     8 
     9         Person p2 = new JeansDecorator(p1);
    10         p2.show();
    11 
    12         Person p3 = new ShirtDecorator(p1);
    13         p3.show();
    14     }
    15 }
    16 
    17 interface Person {
    18     void show();// 显示一个人
    19 }
    20 
    21 abstract class DecoratorPerson implements Person {
    22     private Person person;
    23 
    24     DecoratorPerson(Person person) {
    25         this.person = person;
    26     }
    27 }
    28 
    29 class JeansDecorator extends DecoratorPerson {
    30 
    31     JeansDecorator(Person person) {
    32         super(person);
    33         // TODO Auto-generated constructor stub
    34     }
    35 
    36     @Override
    37     public void show() {
    38         System.out.println("穿牛仔裤的person");
    39 
    40     }
    41 }
    42 
    43 class ShirtDecorator extends DecoratorPerson {
    44 
    45     ShirtDecorator(Person person) {
    46         super(person);
    47         // TODO Auto-generated constructor stub
    48     }
    49 
    50     @Override
    51     public void show() {
    52         System.out.println("穿t恤的person");
    53 
    54     }
    55 
    56 }
    57 
    58 class Zhansan implements Person {
    59 
    60     @Override
    61     public void show() {
    62         System.out.println("没有任何装饰的张三");
    63 
    64     }
    65 
    66 }

      示例2:

      1 package com.qianfeng.decorator;
      2 
      3 import java.io.FileReader;
      4 import java.io.IOException;
      5 import java.io.Reader;
      6 
      7 public class Demo13 {
      8     // LineNumberReader 装饰类,继承了BufferedReader
      9     public static void main(String[] args) throws IOException {
     10         FileReader fr = new FileReader("src/temp.txt");
     11         // LineNumberReader lnr = new LineNumberReader(fr);
     12         // String line = null;
     13         // lnr.setLineNumber(100);
     14         // while ((line = lnr.readLine()) != null) {
     15         // System.out.println(lnr.getLineNumber() + ":" + line);
     16         // }
     17         // lnr.close();
     18 
     19         MyLineNumberReader lnr = new MyLineNumberReader(fr);
     20         String line = null;
     21         // lnr.setLineNumber(1000);
     22         while ((line = lnr.MyReadLine()) != null) {
     23             System.out.println(lnr.getLineNumber() + ":" + line);
     24         }
     25         lnr.myClose();
     26     }
     27 
     28 }
     29 
     30 /*
     31  * setLineNumber():设置起始行号
     32  * 
     33  * myReadLine():每次读取一行
     34  * 
     35  * getLineNumber():获得当前行号
     36  */
     37 class MyBufferedReader {
     38     private Reader r; // 真正读取功能的类
     39     private char[] arr = new char[512];// 相当于缓冲区
     40     private int index; // 数组下标
     41     private int count; // 统计缓冲区中字符个数
     42 
     43     public MyBufferedReader(Reader r) {
     44         this.r = r;
     45     }
     46 
     47     // 实现一次读取一个的功能
     48     public int myRead() throws IOException {
     49         // 缓冲区中是否有数据
     50         if (count == 0) {
     51             // 从文件中读取数据到缓冲区,返回值读取的字符数
     52             count = r.read(arr);
     53             index = 0; // 下标为0
     54         }
     55         if (count < 0) // 文件末尾
     56             return -1;
     57         // 从缓冲区中读取一个字符
     58         int num = arr[index];
     59         index++;// 下标+1
     60         // 数量-1
     61         count--;
     62         return num;
     63 
     64     }
     65 
     66     // 一次读取一行
     67     public String myReadLine() throws IOException {
     68         StringBuilder sb = new StringBuilder();
     69         int num;
     70         while ((num = myRead()) != -1) {
     71             if (num == '
    ')
     72                 continue;
     73             else if (num == '
    ')
     74                 return sb.toString();
     75             else
     76                 sb.append((char) num);
     77         }
     78         return null;
     79     }
     80 
     81     // 关闭流
     82     public void myClose() throws IOException {
     83         r.close();
     84     }
     85 }
     86 
     87 class MyLineNumberReader extends MyBufferedReader {
     88 
     89     private int lineNumber;
     90 
     91     public MyLineNumberReader(Reader r) {
     92         super(r);
     93     }
     94 
     95     public void setLineNumber(int lineNumber) {
     96         this.lineNumber = lineNumber;
     97     }
     98 
     99     public int getLineNumber() {
    100         return this.lineNumber;
    101     }
    102 
    103     // 每次读取一行,行号+1
    104     public String MyReadLine() throws IOException {
    105         ++lineNumber;
    106         return super.myReadLine();
    107     }
    108 
    109 }

      

      未完,待续。

      

      

  • 相关阅读:
    c++ 中pair类模板的用法详解
    求解Catalan数,(大数相乘,大数相除,大数相加)
    POJ--2823--Sliding Window----单调队列问题
    POJ2796 Feel Good -- 单调队列
    Graham扫描法 --求凸包
    山东理工大学第七届ACM校赛-G 飞花的传送门
    NKOJ1236 a^b (数论定理的应用)
    大数相减 C语言
    SPFA ----模板 O(kE) (k一般不超过2)
    C++大数相加
  • 原文地址:https://www.cnblogs.com/enjoy-coding/p/4803613.html
Copyright © 2020-2023  润新知