zoukankan      html  css  js  c++  java
  • 设计模式----装饰模式

    装饰模式(Java IO) 顾名思义,装饰模式,就是对xxx进行包装 其实就是给对象添加新的功能

    2.给对象添加新的功能 有以下两种解决方法 面向对象:

    1.继承

    2.装饰模式

    3.举例:

    A:继承方式

    package cn.itcast_decorate_extends;
    
    public class Phone {
        public void call(){
            
            System.out.println("手机可以打电话");
        }
        
        
    
    }
    
    package cn.itcast_decorate_extends;
    
    public class ColorPhone extends Phone {
    
        @Override
        public void call() {
            System.out.println("手机可以播放彩铃了");
            super.call();
            //System.out.println("手机可以打电话");//不需要自己写这个功能,直接用父类的就好,父类的打电话的基本功能没变
    
            
        }
        
    
    }
    
    package cn.itcast_decorate_extends;
    
    public class MusicAndColorPhone extends ColorPhone {
    
        @Override
        public void call() {
            System.out.println("手机后可以听音乐了");
            super.call();
            
        }
        
        
    
    }
    
    package cn.itcast_decorate_extends;
    
    public class MusicPhone extends Phone {
    
        @Override
        public void call() {
            super.call();
            System.out.println("手机可以听音乐了");
        }
        
    
    }
    
    package cn.itcast_decorate_extends;
    
    public class PhoneTest {
    
        public static void main(String[] args) {
            //最基本的手机类
            Phone phone=new Phone();
            phone.call();
            System.out.println("----------");
            
            //手机可以播放彩铃
            phone=new  ColorPhone();//多态
            phone.call();
            System.out.println("----------");
            
            //手机可以播放音乐
            phone=new MusicAndColorPhone();
            phone.call();
            System.out.println("----------");
            
            
            //手机既可以播放彩铃,也可以听音乐
            phone=new MusicAndColorPhone();
            phone.call();
            System.out.println("----------");
            
            
    
        }
    
    }

    我们应该都有手机,而手机具备打电话的功能 按照正常的思路,现在呢,我们就应该写出一个手机类来。并给出一个电话功能。 随着发展,我们的需求发生了改变,假设我要在打电话之前要听到彩铃,然后再打电话,要怎么做? 我们可以改以前的Phone类,但是不好,因为不是所有人都需要打电话听彩铃 所以 ,现在我们只能重新写一个具备彩铃功能的类

    社会会继续发展,人的需求也是不断变化的。比如说现在又想打完电话后,听到一首音乐。 怎么办? 方案有两种; a.继承ColorPhone b.继承自Phone,自己实现彩铃,接着调用父亲的电话功能,最后自己再实现广告。 这个时候,我们可以任选其一即可,我们选择a方案。

    这个时候,其实我们有些人可能指向具备带电话和音乐功能。 那么,也就是说,我们需要在专门的写一个类实现这个功能。 对扩展开放 对修改关闭

    我们把这个继承的体系写下来

    Phone

      |--ColorPhone     

              |--MusicAndColorPhone

      |--MusicPhone

    如果我没有更多的需求 ,这个继承体系会越变越大,臃肿。 那么,如何解决这个问题呢?这个时候,很多开发者总结一个规律:装饰模式

    B.通过装饰模式来实现  

    package cn.itcast.decorate_decorate;
    
    public interface Phone {
        
        public abstract void call();//默认是public abstract ,虽然都是知道默认是是这种类型
        // 子类的访问修饰符不能低于父类的访问权限修饰符
    
    }
    
    package cn.itcast.decorate_decorate;
    
    public class PhoneImpl implements Phone {
    
        @Override
        public void call() {
            System.out.println("手机可以打电话");
        }
    
    }
    
    package cn.itcast.decorate_decorate;
    
    public abstract class PhoneDecorate implements Phone{
        //传递一个具体的手机给我,我要对你装饰
        private  Phone phone;
        
        public PhoneDecorate(Phone phone){
            this.phone=phone;
        }
        
        @Override
        public void call() {
            this.phone.call();
            
        }
    
    }
    
    package cn.itcast.decorate_decorate;
    
    public class ColorPhoneDecorate extends PhoneDecorate {
    
        
        public ColorPhoneDecorate(Phone phone) {
            super(phone);
        }
    
        @Override
        public void call() {
            System.out.println("手机可以播放彩铃");
            super.call();
        }
        
        
    
    }
    
    package cn.itcast.decorate_decorate;
    
    public class MusicPhoneDecorate extends PhoneDecorate {
    
        public MusicPhoneDecorate(Phone phone) {
            super(phone);
            // TODO Auto-generated constructor stub
        }
    
        @Override
        public void call() {
            // TODO Auto-generated method stub
            super.call();
            System.out.println("手机可以听音乐了");
        }
        
        
        
        
        
        
        
        
    
    }
    
    package cn.itcast.decorate_decorate;
    
    public class PhoneTest {
    
        public static void main(String[] args) {
            // 最基本的手机类
            Phone phone=new PhoneImpl();
            phone.call();
            System.out.println("--------");
            
            //我要装饰手机可以播放彩铃
            PhoneDecorate pd=new ColorPhoneDecorate(phone);
            pd.call();
            System.out.println("--------");
            
            //我要装饰手机可以听音乐
            pd=new ColorPhoneDecorate(phone);
            pd.call();
            System.out.println("--------");
            
            //我要装饰手机可以播放彩铃,也可装饰手机可以听音乐
            pd=new MusicPhoneDecorate(new ColorPhoneDecorate(phone));
            pd.call();
            System.out.println("--------");
            
        }
    
    }

    a:被装饰的抽象事务是谁呢?       手机接口  

    b:具体的手机事物      实现手机接口的具体类  

    c:对手机进行装饰的抽象类    

    d:对手机进行具体的装饰的类

    完事后,我们总结下

    Phone     

            |--PhoneDecrate      

                 |-ColorPhoneDecrate   

                      |-MusicPhoneDecrate   

                      |-GuangGaoPhoneDecrate     

             |--PhoneImpl

    总结如下: 继承会让耦合变得很强  父类改变了,会对子类产生很大的影响,比如父类的某分方法加了点东西,子类也会显现出来。

    4.java的IO流(装饰模式的提现)

    BufferedInputStream BufferedOutputStream

    BufferedReader BufferedWriter

    Writer   

           |--OutputStreamWriter        

                 |--FileWriter   

           |--BufferedWriter

          FileWriter fw=new FileWriter("a.txt");   

          OutputStreamWriter osw=new OutputStreamWriter("b.txt");      

         //Bufferedxxx流其实是对io的记性了缓存处理,为了提高效率      

         BufferedWriter bw=new BufferedWriter(new FileWriter("a.txt"););   

  • 相关阅读:
    centos7下安装erlang
    centos7下升级git版本
    pytest失败重跑插件: pytest-rerunfailures使用与坑(全网独家精华)
    pytest-assume插件(全网最详细解释):多重断言执行
    pytest踩坑记:NameError: name 'pytest' is not defined
    pytest-ordering:指定pytest的case运行顺序的插件
    pytest中print的坑
    pytest测试入门篇(ExitCode退出码)
    httprunner3.x遇到的问题(hrun make报错)
    httprunner3.x(入门介绍篇)
  • 原文地址:https://www.cnblogs.com/vinplezhang/p/3660596.html
Copyright © 2011-2022 走看看