设计模式学习6 -- Decorator(装饰)模式

 

1.   Decorator(装饰)模式

1.1. 概述

l         场景:贵公司编写一个类ReadStrFromFile,专门负责从文件内读取字符串。本来这个功能已经足够了。但是后来发现这些字符串还需要统一变成大写字母。请你编写一个类,能够将字符串转大写字母,并配合上面的类使用,你有何高见?

l         方案1:在主函数内,编写一个类,调用ReadStrFromFile,得到字符串,转大写。

l         方案2:适配器模式,扩展ReadStrFromFile,重写读文件函数

l         评价方案2

1.2. 解决方法1:使用适配器模式

单向适配器模式是在主模块上接入一个扩展模块,用继承法。代码如下:

class ReadStrFromFile{//主模块

       public void read(){

              System.out.println("从文件读取字符串");

              }

       }

 

class Convert{//扩展模块

       public void convertToUpper(){

              System.out.println("转大写字母");

              }

       }

 

//适配器模式:

class SubReadStrFromFile extends ReadStrFromFile{

       private Convert convert;

       public SubReadStrFromFile(Convert convert){

              this.convert = convert;

              }

       public void read(){

              super.read();

              convert.convertToUpper();

              }

       }

 

public class Decorator1{//客户端,最终使用方

       public static void main(String args[]){

              SubReadStrFromFile srsff = new SubReadStrFromFile(new Convert());

              srsff.read();

              }

       }

在上面的代码使用适配器模式,使用适配器有优势也有缺点。

优势:能够很好的应付扩展模块的切换

缺陷:扩展模块无法很好的应付主模块的切换

问题类比:ConvertReadStrFromFile服务,以后又要为ReadStrFromNet服务

用单向适配器模式,就必须为ReadStrFromNet编写子类,很麻烦。

由此我们可以使用装饰模式。

1.3. 解决方法2:使用装饰模式

装饰模式要点:主模块接口注入扩展模块,代码如下:

interface IRead{

       public abstract void read();

       }

class ReadStrFromFile implements IRead{//主模块

       public void read(){

              System.out.println("从文件读取字符串");

              }

       }

      

class ReadStrFromNet implements IRead{//主模块

       public void read(){

              System.out.println("从网络读取字符串");

              }

       }    

 

//装饰模式

class Convert{//扩展模块,可以用Spring装配,可以为任何实现了IRead接口的类服务

       private IRead iread;

       public Convert(IRead iread){

              this.iread = iread;

              }

       public void convertToUpper(){

              iread.read();

              System.out.println("转大写字母");

              }

       }

 

 

public class Decorator2{//客户端,最终使用方

       public static void main(String args[]){        

 

              Convert convert = new Convert(new ReadStrFromNet());

              convert.convertToUpper();

              }

       }

 

1.4. 和适配器的区别

图1

 

1.5. 装饰模式要点

l         编写一个类,包含一个字符串转大写的函数toUpper。在构造函数内传入原来ReadStr类的引用。在toUpper函数内调用ReadStr的方法,并且做相应操作

l         评价这种方法

l         更好的方法:编写一个接口管理待扩充的类

l         练习:编写一个类,能从文件里面读一行,编译在不改变这个类源代码的基础上,增加另一类,使得它能和这个类配合使用,将文件里面读得的内容倒转

l         案例:大家是否记得Java读中文的方法?

l         FileReader是不能读中文的,但是这个类有连接到文件的能力,那你是否编写一个类,使用的时候套在FileReader上面?这就是BufferedReader,其实两者的耦合很小。

l         怎么编写?

l         FileReader fis = new FileREader(“filename”);

l         BufferedReader br = new BufferedReader(fis);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值