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

    装饰与继承的区别:

    装饰:基于已有的功能,并提供加强功能,装饰类通常会通过构造方法接收被装饰的对象。并基于被装饰的对象的功能,提供更强的功能。相对于继承来说装饰模式可以在不使用创造更多子类的情况下,将对象的功能加以扩展。英文叫:Decorator

    继承:因为要扩展某个功能,就得继承父类,然后覆盖重写,导致这个体系更加臃肿,并且内存占用高。

    一般情况下,其实接口也可以当做一种抽象类来看待,也就是说父类对象也可以是接口,如果一个类A实现了一个接口T,当我们在声明实例:T t =new A();时,t看起来是一个T,本质上是一个A,这也是多态的一种!

    验证一下,首先先创建一个接口a:

     1 public class test {
     2    interface a{
     3        void fun();
     4    }
     5    class b implements a{
     6 
     7     public void fun() {
     8         System.out.println("这个实现接口类!");
     9     }
    10        
    11    }
    12    class c extends  b{
    13        public void fun(){
    14            System.out.println("这是实现接口类的子类!!");
    15        }
    16    }
    17    public static void main(String[] args) {
    18         a dd = new test().new c();
    19        dd.fun();
    20     }
    21 }

    运行:

     例1:

    摘自CSDN的一位大神的例子,看这个程序只要多态的功能理清楚也就明白了,说白了装饰模式无非就是多态与构造方法的灵活运用罢了:

      1 public class decorateMode{
      2     //定义被装饰者
      3     public interface Human {
      4         public void wearClothes();
      5 
      6         public void walkToWhere();
      7     }
      8 
      9     //定义装饰者
     10     public abstract class Decorator implements Human {
     11         private Human human;
     12 
     13         public Decorator(Human human) {
     14             this.human = human;
     15         }
     16 
     17         public void wearClothes() {
     18             human.wearClothes();
     19         }
     20 
     21         public void walkToWhere() {
     22             human.walkToWhere();
     23         }
     24     }
     25 
     26     //下面定义三种装饰,这是第一个,第二个第三个功能依次细化,即装饰者的功能越来越多
     27     public class Decorator_zero extends Decorator {
     28 
     29         public Decorator_zero(Human human) {
     30             super(human);
     31         }
     32 
     33         public void goHome() {
     34             System.out.println("进房子。。");
     35         }
     36 
     37         public void findMap() {
     38             System.out.println("书房找找Map。。");
     39         }
     40 
     41         public void wearClothes() {
     42             // TODO Auto-generated method stub
     43             super.wearClothes();
     44             goHome();
     45         }
     46 
     47         public void walkToWhere() {
     48             // TODO Auto-generated method stub
     49             super.walkToWhere();
     50             findMap();
     51         }
     52     }
     53 
     54     public class Decorator_first extends Decorator {
     55 
     56         public Decorator_first(Human human) {
     57             super(human);
     58         }
     59 
     60         public void goClothespress() {
     61             System.out.println("去衣柜找找看。。");
     62         }
     63 
     64         public void findPlaceOnMap() {
     65             System.out.println("在Map上找找。。");
     66         }
     67 
     68         public void wearClothes() {
     69             // TODO Auto-generated method stub
     70             super.wearClothes();
     71             goClothespress();
     72         }
     73 
     74         public void walkToWhere() {
     75             // TODO Auto-generated method stub
     76             super.walkToWhere();
     77             findPlaceOnMap();
     78         }
     79     }
     80 
     81     public class Decorator_two extends Decorator {
     82 
     83         public Decorator_two(Human human) {
     84             super(human);
     85         }
     86 
     87         public void findClothes() {
     88             System.out.println("找到一件D&G。。");
     89         }
     90 
     91         public void findTheTarget() {
     92             System.out.println("在Map上找到神秘花园和城堡。。");
     93         }
     94 
     95         public void wearClothes() {
     96             // TODO Auto-generated method stub
     97             super.wearClothes();
     98             findClothes();
     99         }
    100 
    101         public void walkToWhere() {
    102             // TODO Auto-generated method stub
    103             super.walkToWhere();
    104             findTheTarget();
    105         }
    106     }
    107 
    108     //定义被装饰者,被装饰者初始状态有些自己的装饰
    109     public class Person implements Human {
    110 
    111         public void wearClothes() {
    112             // TODO Auto-generated method stub
    113             System.out.println("穿什么呢。。");
    114         }
    115 
    116         public void walkToWhere() {
    117             // TODO Auto-generated method stub
    118             System.out.println("去哪里呢。。");
    119         }
    120     }
    121     //测试类,看一下你就会发现,跟java的I/O操作有多么相似
    122     public static void main(String[] args) {
    123         decorateMode decorateMode=new decorateMode();
    124         Human person =decorateMode. new Person();
    125         Decorator decorator = decorateMode.new Decorator_two(decorateMode.new Decorator_first(
    126                 decorateMode.new Decorator_zero(person)));
    127         decorator.wearClothes();
    128         decorator.walkToWhere();
    129     }
    130 }

      运行结果:

     例2:

    读取文件的行内容,并给每行前加上行数、行后加上分号

      1 package com.beiwo.Io;
      2 
      3 import java.io.BufferedReader;
      4 import java.io.FileNotFoundException;
      5 import java.io.FileReader;
      6 import java.io.IOException;
      7 import java.io.Reader;
      8 
      9 /*
     10  
     11  BufferedReader : 拓展FileReader的功能。
     12  
     13           需求1 :实现通过readLine读取代码  ,每一行加上一个行号。
     14           需求2 :实现通过readLine读取代码  ,每一行加上一个分号。
     15           需求3 :实现通过readLine读取代码  ,每一行加上一个引号。
     16           
     17   //=========================================================
     18           需求4 :实现通过readLine读取代码  ,每一行加上一个引号 + 行号。
     19           需求5 :实现通过readLine读取代码  ,每一行加上一个分号 + 行号。
     20           需求6 :实现通过readLine读取代码  ,每一行加上一个分号 + 引号。
     21           需求7 :实现通过readLine读取代码  ,每一行加上一个分号 + 引号 + 行号。
     22           
     23      如果用继承:
     24               好处:代码结构和清晰容易理解
     25               缺点:继承体系会很庞大。实现七个需求就得创建七个子类
     26               
     27   
     28   装饰者模式 :  增强一个类的功能还可以让装饰者类之间互相装饰。
     29               
     30     
     31  
     32  */
     33 
     34 //添加行号
     35 class BufferedReaderLineNum extends BufferedReader{
     36     //定义一个对象来接收传进来的对象
     37     BufferedReader bufferedReader;
     38     int count = 1;
     39     
     40     //子类继承父类会默认调用父类的无参构造方法
     41     public BufferedReaderLineNum (BufferedReader in) {
     42         super(in);
     43         this.bufferedReader = in;
     44     }
     45     
     46     //复写readLine方法
     47     @Override
     48     public String readLine() throws IOException {
     49         // TODO Auto-generated method stub
     50         //调用父类的readLine
     51         String content = bufferedReader.readLine();
     52         //给内容田间一个行号
     53         if(content == null){
     54             
     55             return null;
     56         }
     57         content = count+"  "+content;
     58         count++;
     59         return content;
     60     }
     61     
     62 }
     63 
     64 //添加分号的
     65 class BufferedReaderLineSemi extends BufferedReader{
     66     //定义一个对象来接收传进来的对象
     67     BufferedReader bufferedReader;
     68     //子类继承父类会默认调用父类的无参构造方法
     69     public BufferedReaderLineSemi (BufferedReader in) {
     70         super(in);
     71         this.bufferedReader = in;
     72     }
     73     
     74     //复写(重写)readLine方法
     75     @Override
     76     public String readLine() throws IOException {
     77         // TODO Auto-generated method stub 
     78         //调用父类的readLine
     79         String content = bufferedReader.readLine();
     80         //给内容田间一个行号
     81         if(content == null){//表示数据已经读完
     82             
     83             return null;
     84         }
     85         
     86         return content+";";
     87     }
     88     
     89 }
     90 
     91 
     92 
     93 public class Demo1 {
     94 
     95     /**
     96      * @param args
     97      * @throws IOException 
     98      */
     99     public static void main(String[] args) throws IOException {
    100         // TODO Auto-generated method stub
    101         testLineNum();
    102     }
    103     
    104     public static void testLineNum () throws IOException{
    105         
    106         //1.开启一个通道,并且带一个文件路径
    107         FileReader reader = new FileReader("这里填上文件路径如:C:\a.java");
    108         //创建缓冲流
    109         BufferedReader bufferedReader = new BufferedReader(reader);
    110         //2.创建一个带分号的缓冲流
    111         BufferedReaderLineSemi lineSemi = new BufferedReaderLineSemi(bufferedReader);  
    112         //创建一个缓冲流 ,带行号加分号
    113         BufferedReaderLineNum lineNum = new BufferedReaderLineNum(lineSemi);
    114         //3.开始读取数据
    115         String content = null;
    116         while((content = lineNum.readLine())!=null){
    117             
    118             System.out.println(content);
    119         }
    120         
    121         //4.关闭资源
    122         lineNum.close();
    123     }
    124 }

    效果:

  • 相关阅读:
    键盘快捷键
    电脑命令行命令
    网络基础TCP/IP
    运算符优先级
    元字符汇总
    正则表达式
    模板语法(DOM与Vue数据绑定)
    computed、methods、watch
    vue实例
    坐标轴
  • 原文地址:https://www.cnblogs.com/qq1871707128/p/6142157.html
Copyright © 2011-2022 走看看