设计模式:三段代码让你理解 装饰者模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_41548307/article/details/83421510

package com.zx.b_decorator;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

/*
 * 
 * 需求1:  编写一个类对 BufferedReader的功能进行增强,增强readLine方法,返回数据带有行号
 * 需求2: 编写一个类 对 BufferedReader的功能进行增强,增强readLine方法,返回数据带有分号
 * 需求3: 编写一个类 对 BufferedReader的功能进行增强,增强readLine方法,返回数据带有双引号
 * 需求4: 编写一个类 对 BufferedReader的功能进行增强,增强readLine方法,返回数据带有行号+分号
 * 需求5: 编写一个类 对 BufferedReader的功能进行增强,增强readLine方法,返回数据带有行号+双引号
 * 需求6: 编写一个类 对 BufferedReader的功能进行增强,增强readLine方法,返回数据带有分号+双引号
 * 需求7: 编写一个类 对 BufferedReader的功能进行增强,增强readLine方法,返回数据带有行号+分号+双引号
 * 
 * 增强一个类的功能:
 * 	通过继承 增强一个类的功能的优点:代码结构清晰,简单
 * 	缺点: 代码不灵活,而且导致 继承体系 过于庞大
 * 
 * 解决方案:使用继承,通过子类 去增强其功能
 * 
 * 
 * 	
 * 
 * 
 * --|BufferedReader
 * 		--| BufferedLineNum  readLine方法加行号
 * 		--| BufferedSemi	readLine方法加分号
 * 		--| BufferedQuto	readLine方法加双引号
 * 		--|
 * 		--|
 * 		--|
 * 	
 * 
 * 
 * */

//加行号的缓冲类
class BufferedLineNum extends BufferedReader{

	int count = 1; // 行号
	
	public BufferedLineNum(Reader in) {
		super(in);
	}
	
	@Override
	public String readLine() throws IOException {
		
		String line = super.readLine();
		
		//读到文件末尾
		if(line == null){
			return null;
		}
		
		return count++ +":"+line;
	}
	
}

//加分号的缓冲类
class BufferedSemi extends BufferedReader{
	
	public BufferedSemi(Reader in) {
		super(in);
	}
	
	@Override
	public String readLine() throws IOException {
		
		String line = super.readLine();
		
		//读到文件末尾
		if(line == null){
			return null;
		}
		
		return line+";";
	}
	
}

//带有双引号的缓冲类
class BufferedQuto extends BufferedReader{
	
	public BufferedQuto(Reader in) {
		super(in);
	}
	
	@Override
	public String readLine() throws IOException {
		
		String line = super.readLine();
		
		//读到文件末尾
		if(line == null){
			return null;
		}
		
		return "\""+line+"\"";
	}
	
}

//行号+分号
class BufferedSemiAndLineNum extends BufferedLineNum{

	public BufferedSemiAndLineNum(Reader in) {
		super(in);
		// TODO Auto-generated constructor stub
	}
	
}
//行号+双引号
class BufferedLineNumAndQuto extends BufferedLineNum{

	public BufferedLineNumAndQuto(Reader in) {
		super(in);
		// TODO Auto-generated constructor stub
	}
	
}

//行号+双引号+分号
class BufferedLineNumAndQutoAndSemi extends BufferedLineNumAndQuto{

	public BufferedLineNumAndQutoAndSemi(Reader in) {
		super(in);
		// TODO Auto-generated constructor stub
	}
	
}


public class Demo1 {

	public static void main(String[] args) throws IOException {
	
		File file = new File("d://user.txt");
		
		//行号
		//BufferedLineNum bln = new BufferedLineNum(new FileReader(file));
		//分号
		BufferedSemi bs = new BufferedSemi(new FileReader(file));
		//双引号
		//BufferedQuto bq = new BufferedQuto(new FileReader(file));
		
		String line = null;
		
		while((line = bs.readLine())!=null){
			System.out.println(line);
		}
	}
}
/*
 * 需求: 在每行前面加一个行号
 * 解决方案: 希望readLine方法返回给我们的就是一个带需要的内容
 * 			对BufferedReader的 readLine方法进行增强,这时候可以使用装饰者模式
 * 	
 * 装饰者模式
 * 概念: 装饰者 和 被装饰者
 * 		BufferedReader 就是 被装饰者
 * 
 * 步骤:
 * 	1)编写一个 BufferedReader装饰者类,继承被装饰者类(不能是final的)
 * 	2)在装饰者类中定义一个成员变量,用于接收被装饰者对象
 * 	3)在装饰者类的构造方法中传入被装饰者对象
 * 		使用第二步定义的成员变量接收被传入的 被装饰者
 * 	4)在装饰者类中重写被装饰者类方法,对方法进行增强
 * 
 * 注意:
 * 	1.让装饰者与被装饰者 有一个共同的父类或者父接口
 * 
 * 装饰者设计模式
 * 	好处:	利用了多态达到了 类 与 类 之间的互相修饰,比较灵活
 * 	缺点:	代码结构不清晰,难以理解
 * 
 * 	
 * 	
 * 
 * 
 * */
//加行号的缓冲类
class BufferedLineNum2 extends BufferedReader{

	BufferedReader br;
	
	int count = 1;
	
	public BufferedLineNum2(BufferedReader br) {
		super(br);
		this.br=  br;
		
	}
	
	@Override
	public String readLine() throws IOException {
		
		//被装饰者 的 readLine方法(就是 没有被增强的readLine方法)
		String line = br.readLine();
		
		if(line == null){
			return null;
		}
		return count++ +":"+line;
				
	}

}

//带双引号的缓冲流
class BufferedQuto2 extends BufferedReader{

	BufferedReader br;
	
	public BufferedQuto2(BufferedReader br) {
		super(br);
		this.br=  br;
		
	}
	
	@Override
	public String readLine() throws IOException {
		
		//被装饰者 的 readLine方法(就是 没有被增强的readLine方法)
		String line = br.readLine();
		
		if(line == null){
			return null;
		}
		return "\""+line+"\"";
				
	}

}

//带分号的缓冲流
class BufferedSemi2 extends BufferedReader{

	BufferedReader br;
	
	public BufferedSemi2(BufferedReader br) {
		super(br);
		this.br=  br;
		
	}
	
	@Override
	public String readLine() throws IOException {
		
		//被装饰者 的 readLine方法(就是 没有被增强的readLine方法)
		String line = br.readLine();
		
		if(line == null){
			return null;
		}
		return line+";";
				
	}

}

public class Demo2 {

	public static void main(String[] args) throws IOException {
		//被装饰者对象
		BufferedReader br = new BufferedReader(new FileReader(new File("d://user.txt")));

		//创建一个带行号的缓冲输入字符流:传入被装饰者对象
		BufferedLineNum2 lineNum = new BufferedLineNum2(br);
		//创建一个带双引号的缓冲输入字符流:传入被装饰者对象
		BufferedQuto2 quto = new BufferedQuto2(br);
		//创建一个带分号的缓冲输入字符流:传入被装饰者对象
		BufferedSemi2 semi = new BufferedSemi2(br);
		//行号+双引号
		// BufferedQuto2 作为 修饰者,BufferedLineNum2作为被修饰者
		BufferedQuto2 qutoAndLinenum = new BufferedQuto2(lineNum);
		//行号+分号
		BufferedSemi2 semiAndLinenum = new BufferedSemi2(lineNum);
		
		//分号+双引号
		
		
		//分号+双引号+行号
		
		
		String line = null;
		while((line = semiAndLinenum.readLine())!=null){
			System.out.println(line);
		}
		
	}
}
/*
 * 需求:一家三口 画一幅画,儿子负责绘画
 * 					妈妈负责上色,涂颜料
 * 					爸爸负责上画框
 * 
 * 
 * */

interface Draw{
	void draw();
}

class Son implements Draw{

	@Override
	public void draw() {
		System.out.println("儿子正在画画...");
		
	}
	
}

class Mother implements Draw{

	//在内部维护一个 需要被增强的类
	Draw d;
	public Mother(Draw d){
		this.d = d;
	}
	
	@Override
	public void draw() {
		 //被装饰者 原先的功能
		d.draw(); 
		//对 功能进行增强
		System.out.println("妈妈上涂料...");
		
	}
	
}

class Father implements Draw{

	Draw d;
	public Father(Draw d){
		this.d = d;
	}
	
	
	@Override
	public void draw() {
		
		d.draw();
		System.out.println("爸爸上画框...");
		
	}
	
}


public class Demo3 {
	
	public static void main(String[] args) {
	
		Son s = new Son();
		Mother m = new Mother(s);
		Father f = new Father(m);
		
		f.draw();
	}

}

猜你喜欢

转载自blog.csdn.net/qq_41548307/article/details/83421510