您的位置:首页 > 其它

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

2009-11-12 13:00 706 查看

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();
}
}
在上面的代码使用适配器模式,使用适配器有优势也有缺点。
优势:能够很好的应付扩展模块的切换
缺陷:扩展模块无法很好的应付主模块的切换
问题类比:Convert为ReadStrFromFile服务,以后又要为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.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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: