游学旅行网站建设策划书,wordpress 邮件代发,云南建设监理协会官方网站,最近实时热点新闻事件1、概述
我们先来看一个快餐店的例子。
快餐店有炒面、炒饭这些快餐#xff0c;可以额外附加鸡蛋、火腿、培根这些配菜#xff0c;当然加配菜需要额外加钱#xff0c;每个配菜的价钱通常不太一样#xff0c;那么计算总价就会显得比较麻烦。 使用继承的方式存在的问题可以额外附加鸡蛋、火腿、培根这些配菜当然加配菜需要额外加钱每个配菜的价钱通常不太一样那么计算总价就会显得比较麻烦。 使用继承的方式存在的问题 扩展性不好 如果要再加一种配料火腿肠我们就会发现需要给FriedRice和FriedNoodles分别定义一个子类。如果要新增一个快餐品类炒河粉的话就需要定义更多的子类。 产生过多的子类
定义
指在不改变现有对象结构的情况下动态地给该对象增加一些职责即增加其额外功能的模式。
2、结构
装饰Decorator模式中的角色 抽象构件Component角色 定义一个抽象接口以规范准备接收附加责任的对象。上图中的抽象快餐类 具体构件ConcreteComponent角色 实现抽象构件通过装饰角色为其添加一些职责。炒米粉炒面等具体角色 抽象装饰Decorator角色 继承或实现抽象构件并包含具体构件的实例可以通过其子类扩展具体构件的功能。加鸡蛋加火腿抽象类 具体装饰ConcreteDecorator角色 实现抽象装饰的相关方法并给具体构件对象添加附加的责任。具体加鸡蛋还是加火腿
3、案例
我们使用装饰者模式对快餐店案例进行改进体会装饰者模式的精髓。
类图如下 代码如下
//快餐接口
public abstract class FastFood {private float price;private String desc;
public FastFood() {}
public FastFood(float price, String desc) {this.price price;this.desc desc;}
public void setPrice(float price) {this.price price;}
public float getPrice() {return price;}
public String getDesc() {return desc;}
public void setDesc(String desc) {this.desc desc;}
public abstract float cost(); //获取价格
}
//炒饭
public class FriedRice extends FastFood {
public FriedRice() {super(10, 炒饭);}
public float cost() {return getPrice();}
}
//炒面
public class FriedNoodles extends FastFood {
public FriedNoodles() {super(12, 炒面);}
public float cost() {return getPrice();}
}
//配料类 装饰者
public abstract class Garnish extends FastFood {
private FastFood fastFood;
public FastFood getFastFood() {return fastFood;}
public void setFastFood(FastFood fastFood) {this.fastFood fastFood;}
public Garnish(FastFood fastFood, float price, String desc) {super(price,desc);this.fastFood fastFood;}
}
//鸡蛋配料
public class Egg extends Garnish {
public Egg(FastFood fastFood) {super(fastFood,1,鸡蛋);}
public float cost() {return getPrice() getFastFood().getPrice();}
Overridepublic String getDesc() {return super.getDesc() getFastFood().getDesc();}
}
//培根配料
public class Bacon extends Garnish {
public Bacon(FastFood fastFood) {
super(fastFood,2,培根);}
Overridepublic float cost() {return getPrice() getFastFood().getPrice();}
Overridepublic String getDesc() {return super.getDesc() getFastFood().getDesc();}
}
//测试类
public class Client {public static void main(String[] args) {//点一份炒饭FastFood food new FriedRice();
System.out.println(food.getDesc() food.cost() 元);
System.out.println();
//在上面的炒饭中加一个鸡蛋food new Egg(food);System.out.println(food.getDesc() food.cost() 元);
System.out.println();//再加一个鸡蛋food new Egg(food);System.out.println(food.getDesc() food.cost() 元);
System.out.println();food new Bacon(food);System.out.println(food.getDesc() food.cost() 元);}
}
测试结果 好处 装饰者模式可以带来比继承更加灵活性的扩展功能使用更加方便可以通过组合不同的装饰者对象来获取具有不同行为状态的多样化的结果。装饰者模式比继承更具良好的扩展性完美的遵循开闭原则继承是静态的附加责任装饰者则是动态的附加责任。 装饰类和被装饰类可以独立发展不会相互耦合装饰模式是继承的一个替代模式装饰模式可以动态扩展一个实现类的功能。
4、使用场景 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。 不能采用继承的情况主要有两类 第一类是系统中存在大量独立的扩展为支持每一种组合将产生大量的子类使得子类数目呈爆炸性增长 第二类是因为类定义不能继承如final类 在不影响其他对象的情况下以动态、透明的方式给单个对象添加职责。 当对象的功能要求可以动态地添加也可以在动态地撤销时。比如鸡蛋已经卖完了这时候只需要移除鸡蛋类就可以了。
5、JDK源码解析
IO流中的包装类使用到了装饰者模式。BufferedInputStreamBufferedOutputStreamBufferedReaderBufferedWriter。
我们以BufferedWriter举例来说明先看看如何使用BufferedWriter
public class Demo {public static void main(String[] args) throws Exception{//创建BufferedWriter对象//创建FileWriter对象FileWriter fw new FileWriter(C:\\Users\\Think\\Desktop\\a.txt);BufferedWriter bw new BufferedWriter(fw);
//写数据bw.write(hello Buffered);
bw.close();}
}
使用起来感觉确实像是装饰者模式接下来看它们的结构 小结 BufferedWriter使用装饰者模式对Writer子实现类进行了增强添加了缓冲区提高了写数据的效率。