课程名称:Java设计模式精讲 Debug方式+内存分析
课程章节:第11章 装饰者模式讲解+Coding+源码解析
主讲老师:Geely
课程内容:
问题1)定义和作用,实现方式?
不改变原有对象基础之上,将功能附加到对象上
提供了比继承更有弹性的替代方案(扩展原有对象功能上) 1,**作用:**现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
**2,****具体操作:**装饰者类和被装饰者都继承被装饰者抽象类。被装饰抽象类作为成员变量传入装饰者类中(通过构造器), 这样就是可以在装饰者类中操作被装饰对象。
_装饰模式实现方式:_A接口和A接口实现, B装饰器抽象类实现A接口(引入接口引用),B实现类实现A装饰抽象类(调用A接口的实现方法做扩展)
3,包含的类和接口;
装饰器模式主要包含以下角色:
1.抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。
2.具体构件(ConcreteComponent)角色:实现抽象构件,通过装饰角色为其添加一些职责。
3.抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
4.具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。
简化理解:
1,A接口 2,实现A接口类 3,B抽象实现接口类(接口引用,要求传入实现类) 4,实现B抽象类 (传入实现类,调用实现类方法 + 附加功能)
问题2)使用场景?
扩展一个类的功能或给一个类添加附加职责。
动态的给一个对象添加功能,这些功能可以再动态的撤销。
场景:买煎饼可以加鸡蛋,加香肠。要一个加三个鸡蛋和两个香肠的煎饼,使用继承就得创建(三个鸡蛋和两个香肠的煎饼子类)一个子类进行实现,而装饰器只需要创建一个鸡蛋子类和香肠子类。
问题3)优点和缺点?
优点第五条是主要的优点: 1, 装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用 2,通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果 3,装饰器模式完全遵守开闭原则 4, 扩展一个类的功能,动态增加功能,动态撤销。 5**,为什么继承无法实现的要用装饰,例如:鸡蛋煎饼,接口是煎饼,煎饼实现类加了一个鸡蛋,若加2个鸡蛋,就要再做一个实现类,加三个又是一个实现类,加两根辣条,加三根辣条。装饰:只需要实现煎饼接口,加几个鸡蛋和几根辣条都是可以直接添加,不需要继承实现更多子类**
缺点:
1,子类增多
2,动态装饰时候,多层装饰时会更复杂。
问题4)装饰者和代理模式,装饰者和适配器模式区别?
装饰者模式和代理模式:装饰者模式关注对象的动态添加方法。
代理模式关注控制对对象的访问。
**在使用上:**代理模式中的代理类创建被代理对象的实例,对于客户端代理对象是被代理类隐藏的。
装饰者模式是不隐藏被装饰类的,被装饰者作为构造器参数传入装饰类。
装饰者模式和适配器模式都是包装模式。
装饰者和被装饰者可以实现相同的接口。
适配器和被适配器是实现不同的接口。
问题5)装饰者模式的例子?
**场景:买煎饼可以加鸡蛋,加香肠。**要一个加三个鸡蛋和两个香肠的煎饼,使用继承就得创建(三个鸡蛋和两个香肠的煎饼子类)一个子类进行实现,而装饰器只需要创建一个鸡蛋子类和香肠子类。
public class decorateTest02 {
public static void main(String[] args) {
//来个炒面
FastFood fastFood=new FriedNoodles();
System.out.println(fastFood.getDesc()+"\t"+fastFood.cost()+"元");
//加个鸡蛋
fastFood=new Egg(fastFood);
System.out.println(fastFood.getDesc()+"\t"+fastFood.cost()+"元");
//再加个鸡蛋
fastFood=new Egg(fastFood);
System.out.println(fastFood.getDesc()+"\t"+fastFood.cost()+"元");
//再加个培根
fastFood=new Bacon(fastFood);
System.out.println(fastFood.getDesc()+"\t"+fastFood.cost()+"元");
}
}
//快餐接口--抽象类或接口实现都可以
abstract class FastFood {
private float price;
private String desc;
FastFood() {
}
FastFood(float price, String desc) {
this.price = price;
this.desc = desc;
}
void setPrice(float price) {
this.price = price;
}
float getPrice() {
return price;
}
String getDesc() {
return desc;
}
void setDesc(String desc) {
this.desc = desc;
}
abstract float cost(); //获取价格
}
//炒饭
class FriedRice extends FastFood {
FriedRice() {
super(10, "炒饭");
}
float cost() {
return getPrice();
}
}
//炒面
class FriedNoodles extends FastFood {
FriedNoodles() {
super(12, "炒面");
}
float cost() {
return getPrice();
}
}
/**
* 抽象装饰
* 即继承自FastFood,又聚合FastFood
*/
abstract class Garnish extends FastFood{
private FastFood fastFood;
Garnish() {
}
FastFood getFastFood() {
return fastFood;
}
void setFastFood(FastFood fastFood) {
this.fastFood = fastFood;
}
Garnish(FastFood fastFood,float price, String desc) {
super(price, desc);
this.fastFood = fastFood;
}
}
class Egg extends Garnish{
Egg(FastFood fastFood) {
super(fastFood, 2, "鸡蛋");
}
@Override
float cost() {
return getPrice()+getFastFood().cost();
}
@Override
String getDesc() {
String str1=super.getDesc();
String str2=getFastFood().getDesc();
return str1+str2;
}
}
class Bacon extends Garnish{
Bacon(FastFood fastFood) {
super(fastFood, 5, "培根");
}
float cost() {
return getPrice()+getFastFood().cost();
}
@Override
String getDesc() {
return super.getDesc()+getFastFood().getDesc();
}
}
问题6)装饰者模式在jdk源码中的应用?
Decorator肯定是装饰者模式、
但是wrapper有可能是适配器模式也有可能是装饰者模式。要看类当中的具体实现。
因为两个设计模式都叫包装类模式。
共同学习,写下你的评论
评论加载中...
作者其他优质文章