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