标签:des style blog http java os io for
解决的问题是:我有一个类A,里面可能须要非常多不同行为的功能。
如今有三种解决方法,第一种:每一个功能都弄成一个类,然后继承类A,这样的的问题是,假设功能非常多,会造成类爆炸。
另外一种:我将功能类组合上类A上,这样的想法是好的,但还没够弹性,由于这样我没法在不改动类A的情况下对功能的动态添删。(我的目的就是在不改动类A的情况下,对类A进行功能扩展)
第三种:就是我要说的装饰者模式。
举个样例,我有一个饮品店,我有非常多饮料,也有非常多调料,我通过对饮料搭配不同种类和不同数量的调料,来组合成我的饮品。对吧,由于有非常多种组合,所以这里须要动态组合。
所以我须要一个被装饰者类(饮料和调料的总类,即须要被装饰的内核类):
public abstract class Beverage { String description = "Unknown Beverage"; public String getDescription() { return description; } public abstract double cost(); }
public abstract class CondimentDecorator extends Beverage { public abstract String getDescription(); }
public class Espresso extends Beverage { public Espresso() { description = "Espresso"; } public double cost() { return 1.99; } }
public class HouseBlend extends Beverage { public HouseBlend() { description = "House Blend Coffee"; } public double cost() { return .89; } }
public class Mocha extends CondimentDecorator { Beverage beverage; public Mocha(Beverage beverage) { this.beverage = beverage; } public String getDescription() { return beverage.getDescription() + ", Mocha"; } public double cost() { return .20 + beverage.cost(); } }
public class Whip extends CondimentDecorator { Beverage beverage; public Whip(Beverage beverage) { this.beverage = beverage; } public String getDescription() { return beverage.getDescription() + ", Whip"; } public double cost() { return .10 + beverage.cost(); } }
public class Soy extends CondimentDecorator { Beverage beverage; public Soy(Beverage beverage) { this.beverage = beverage; } public String getDescription() { return beverage.getDescription() + ", Soy"; } public double cost() { return .15 + beverage.cost(); } }
public class StarbuzzCoffee { public static void main(String args[]) { Beverage beverage = new Espresso(); System.out.println(beverage.getDescription() + " $" + beverage.cost()); Beverage beverage2 = new DarkRoast(); beverage2 = new Mocha(beverage2); beverage2 = new Mocha(beverage2);/*这里就解析了为什么我须要饮料和调料同一类型了。如果不同的类型,我如果饮料为A类(被装饰者),调料为B类,我第一次装饰时,我实例化后,那个被装饰者就变成B类型的,我在此基础上再装饰还有一个调料,由于我须要传一个A类型的进去,但我的已经变成B类型了,所以就不能再装饰第二次了。同类型的就解决问题了*/ beverage2 = new Whip(beverage2); System.out.println(beverage2.getDescription() + " $" + beverage2.cost()); Beverage beverage3 = new HouseBlend(); beverage3 = new Soy(beverage3); beverage3 = new Mocha(beverage3); beverage3 = new Whip(beverage3); System.out.println(beverage3.getDescription() + " $" + beverage3.cost()); } }
还记得java中的i/o流不,没错,java.io类就是用装饰者模式的。记得大一时初次学java,看i/o流这部分最烦了,也不懂它的原理,它的类也非常多。如今知道它的运作了:
以InputStream为例,它的“饮料”有FileInputStream,StringBufferInputStream,ByteArrayInputStream,
它的“调料”总类是:FilterInputStream,
装饰者是:BufferedInputStream,DataInputStream,LineNumberInputStream等。
我来自己写一个i/o的装饰者类来加深理解吧:
import java.io.*; public class LowerCaseInputStream extends FilterInputStream { public LowerCaseInputStream(InputStream in) { super(in); } public int read() throws IOException { int c = super.read(); return (c == -1 ? c : Character.toLowerCase((char)c)); } public int read(byte[] b, int offset, int len) throws IOException { int result = super.read(b, offset, len); for (int i = offset; i < offset+result; i++) { b[i] = (byte)Character.toLowerCase((char)b[i]); } return result; } }
import java.io.*; public class InputTest { public static void main(String[] args) throws IOException { int c; try { InputStream in = new LowerCaseInputStream( new BufferedInputStream( new FileInputStream("test.txt"))); while((c = in.read()) >= 0) { System.out.print((char)c); } in.close(); } catch (IOException e) { e.printStackTrace(); } } }
很多其它设计模式解说,关注我吧,我会不时地更新,还有我还会发一些其它如java方法、框架、Linux等一些的心得,我会努力成为大神,并帮助大家一起成为大神的。
标签:des style blog http java os io for
原文地址:http://www.cnblogs.com/mfrbuaa/p/3916467.html