代码改变世界

设计模式----装饰模式

2014-04-12 16:40  VinpleZhang  阅读(227)  评论(0编辑  收藏  举报

装饰模式(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"););