• 常用设计模式__之【装饰设计模式】



    装饰模式的体现之一:

    BufferedReader 类中readLine()方法

    原理readLine()调用的还是read()方法,在硬盘上一个一个的读取,暂时存储起来,当读取到换行符时就把读取的值返回完成一行数据的读取

    模拟BufferedReader类中readLine方法

    import java.io.*;
    class MyBufferedReader 
    {
    	private FileReader r;	//私有化成员变量
    	MyBufferedReader(FileReader r)//将读取流对象传入构造函数
    	{	
    		this.r=r;
    	}
    	public String myReadLine() throws IOException//可以一次读取一行的方法
    	{//定义临时容器,原BufferReader封装了字符数组
    		StringBuilder sb = new StringBuilder();//最终数据还是要转成字符串,为了方便,定义StringBuilder容器
    		int ch = 0;
    		while ((ch=r.read()) !=-1)
    		{					
    			if (ch=='
    ')//Windows中java换行符是 
    
    				continue;//
    			if (ch=='
    ')
    				return sb.toString();//当读取到换行时,将缓冲区中字符串返回
    			else
    				sb.append((char)ch);//读取不到换行,缓冲区就一直增加,由于ch是read返回的该字符在码表中的int值,所以要强转
    		}
    		if(sb.length() !=0)		//此判断是为了处理文件末尾没有换行符的情况
    			return sb.toString();
    		return null;//方法明确了返回值为String,
    	}
    	public void myClose() throws IOException
    	{
    		r.close();
    	}
    }
    readLine()是read()方法的增强,BufferedReader是FileReader类的增强类,
    将被增强类的对象作为参数传入增强类 

    装饰设计模式

    当想要对已有对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,提供加强功能,自定的该类称为装饰类

    示例:

    class Person{
    	public void eat(){
    		System.out.println("吃饭");
    	}
    }
    class SuperPerson{//装饰类
    	private Person p;	//将被装饰的类作为成员变量
    	SuperPerson(Person p){//嵌入到装饰类
    		this.p = p;
    	}
    	public void superEat(){	//装饰类更强大的功能
    		System.out.println("开胃菜");
    		p.eat();
    		System.out.println("饭后甜点");
    		System.out.println("Smoke~");
    	}
    }
    class  DecorateDemo{
    	public static void main(String[] args) {
    		Person p = new Person();
    		SuperPerson sp = new SuperPerson(p);
    		sp.superEat();
    	}
    }

    装饰和继承的关系:

    通过继承生成子类同样可以达到扩展功能的效果,但是相比之下,装饰模式降低了两个类之间的关联度,具有更高的灵活性和扩展性

    MyReader//专门用于读取数据的类。
    	|--MyTextReader
    		|--MyBufferTextReader
    	|--MyMediaReader
    		|--MyBufferMediaReader
    	|--MyDataReader
    		|--MyBufferDataReader
    class MyBufferReader{
    	MyBufferReader(MyTextReader text)
    	{}
    	MyBufferReader(MyMediaReader media)
    	{}
    }
    上面这个类扩展性很差。找到其参数的共同类型。通过多态的形式。可以提高扩展性。

    class MyBufferReader extends MyReader{//组合结构
    	private MyReader r;
    	MyBufferReader(MyReader r)
    	{}
    }

    通过继承将每一个子类都具备缓冲功能。而继承体系比较复杂,并不利于扩展。
    现在优化思想。单独描述一下缓冲内容。将需要被缓冲的对象。传递进来。
    也就是,谁需要被缓冲,谁就作为参数传递给缓冲区。这样继承体系就变得很简单。优化了体系结构。

    优化后的体系:

    MyReader//专门用于读取数据的类。
    	|--MyTextReader
    	|--MyMediaReader
    	|--MyDataReader
    	|--MyBufferReader//

    装饰模式比继承要灵活。避免了继承体系臃肿。而且降低了类于类之间的关系。
    装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。所以装饰类和被装饰类通常是都属于一个体系中的。

    装饰模式的体现之二:

    BufferedReader的子类LineNumberReader
    主要方法:setLineNumber(int x),设置当前行号
    和getLineNumber(),获得当前行号

    示例:

    import java.io.*;
    class  LineNumberReaderDemo	
    {
    	public static void main(String[] args) throws IOException
    	{
    		FileReader fr = new FileReader("LineNumberReaderDemo.java");
    		LineNumberReader lnr = new LineNumberReader(fr);
    		String line = null;
    		lnr.setLineNumber(10);//设置当前行号
    		while ((line=lnr.readLine()) !=null)
    		{
    			System.out.println(lnr.getLineNumber()+" : "+line);
    		}
    		lnr.close();
    	}
    }

    手动模拟实现一个LineNumberReader类

    class MyLineNumberReader extends MyBufferedReader //继承,参考之前的readLine()实现
    {
    	MyLineNumberReader(Reader r){	//继承自父类,省略成员的私有化步奏
    		super(r);
    	}
    	public String myReadLine() throws IOException{
    		lineNumber++;			//相对于父类的readline()仅增加了计数功能
    		return super.myReadLine();//继承自父类
    	}
    	public void setLineNumber(int lineNumber){	//子类特有方法
    		this.lineNumber = lineNumber;
    	}
    	public int getLineNumber(){	//子类特有方法
    		return lineNumber;
    	}//关闭流的动作父类中已经实现了,不需要再覆盖,直接调用即可
    }


  • 相关阅读:
    PAT Basic 1023 组个最小数 (20 分)
    PAT Advanced 1048 Find Coins (25 分)
    PAT Basic 1005 继续(3n+1)猜想 (25 分)
    PAT Advanced 1050 String Subtraction (20 分)
    PAT Advanced 1041 Be Unique (20 分)
    PAT Basic 1047 编程团体赛 (20 分)
    SpringSecurity整合SpringBoot
    给正在运行的Docker容器动态绑定卷组
    linux 中格式化json字符串
    docker/kubernetes国内源/镜像源解决方式
  • 原文地址:https://www.cnblogs.com/Joure/p/4337214.html
Copyright © 2020-2023  润新知