大厂面试必备之设计模式:漫画装饰者模式
Posted 天才少年_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了大厂面试必备之设计模式:漫画装饰者模式相关的知识,希望对你有一定的参考价值。
小安实现的代码如下:
/**
* @Author: 欢迎关注公众号:程序员小安
* @description:价格基类
* 配菜通过成员变量动态设置
* @CreateDate: 2020/3/6
* @Version: 1.0
*/
public abstract class Price
private boolean isNeedVegetables;//是否要青菜
private boolean isNeedFlammulinaVelutipes;//是否需要金针菇
private boolean isNeedDuckBlood;//是否需要鸭血
private boolean isNeedSprouts;//是否需要豆芽
/**
* 获取价格
* @return
*/
public double getPrice()
double totalPrice = 0.0;
if(isNeedVegetables())
totalPrice += 8.9;
if(isNeedFlammulinaVelutipes())
totalPrice += 6.9;
if(isNeedDuckBlood())
totalPrice += 11.9;
if(isNeedSprouts())
totalPrice += 4.9;
return totalPrice;
public boolean isNeedVegetables()
return isNeedVegetables;
public void setNeedVegetables(boolean needVegetables)
isNeedVegetables = needVegetables;
public boolean isNeedFlammulinaVelutipes()
return isNeedFlammulinaVelutipes;
public void setNeedFlammulinaVelutipes(boolean needFlammulinaVelutipes)
isNeedFlammulinaVelutipes = needFlammulinaVelutipes;
public boolean isNeedDuckBlood()
return isNeedDuckBlood;
public void setNeedDuckBlood(boolean needDuckBlood)
isNeedDuckBlood = needDuckBlood;
public boolean isNeedSprouts()
return isNeedSprouts;
public void setNeedSprouts(boolean needSprouts)
isNeedSprouts = needSprouts;
/**
* @Author: 欢迎关注公众号:程序员小安
* @description:鸳鸯锅底
* @CreateDate: 2020/3/6
* @Version: 1.0
*/
public class MandarinDuckPrice extends Price
@Override
public double getPrice()
return 88.0+ super.getPrice();
/**
* @Author: 欢迎关注公众号:程序员小安
* @description:骨头汤锅底
* @CreateDate: 2020/3/6
* @Version: 1.0
*/
public class BonepPrice extends Price
@Override
public double getPrice()
return 68.0 + super.getPrice();
/**
* @Author: 欢迎关注公众号:程序员小安
* @description:四格锅底
* @CreateDate: 2020/3/6
* @Version: 1.0
*/
public class FourGridPrice extends Price
@Override
public double getPrice()
return 118.0 + super.getPrice();
/**
* @Author: 欢迎关注公众号:程序员小安
* @description:用户点餐类
* @CreateDate: 2020/3/6
* @Version: 1.0
*/
public class User
public static void main(String[] args)
MandarinDuckPrice mandarinDuckPrice = new MandarinDuckPrice();//用户选中鸳鸯锅底
mandarinDuckPrice.setNeedVegetables(true);//用户需要青菜
mandarinDuckPrice.setNeedFlammulinaVelutipes(true);//用户需要金针菇
System.out.println("您需要支付金额为:"+mandarinDuckPrice.getPrice());//输出总金额
运行结果:
您需要支付金额为:103.8
装饰者模式:
动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
官方定义不太好理解,我翻译一下,在装饰者模式中,装饰者和被装饰者继承相同的基类,装饰者可以在要求被装饰者前或者后面加上自己的行为,达到特定的目的。比如青菜价格加在鸳鸯锅底的价格前面,然后再动态的用金针菇价格加在青菜价格前面。
采用策略模式的UML图:
价格抽象类:
/**
* @Author: 欢迎关注公众号:程序员小安
* @description: 价格抽象类
* @CreateDate: 2020/3/6
* @Version: 1.0
*/
public abstract class Price
/**
* 获取价格
* @return
*/
public abstract double getPrice();
被装饰者:
/**
* @Author: 欢迎关注公众号:程序员小安
* @description:鸳鸯锅底(具体被装饰者类)
* @CreateDate: 2020/3/6
* @Version: 1.0
*/
public class MandarinDuckPrice extends Price
@Override
public double getPrice()
return 88.0;
/**
* @Author: 欢迎关注公众号:程序员小安
* @description:四格锅底(具体被装饰者类)
* @CreateDate: 2020/3/6
* @Version: 1.0
*/
public class FourGridPrice extends Price
@Override
public double getPrice()
return 118.0;
/**
* @Author: 欢迎关注公众号:程序员小安
* @description:骨头汤锅底(具体被装饰者类)
* @CreateDate: 2020/3/6
* @Version: 1.0
*/
public class BonepPrice extends Price
@Override
public double getPrice()
return 68.0;
装饰者:
/**
* @Author: 欢迎关注公众号:程序员小安
* @description:青菜价格(具体装饰者类)
* @CreateDate: 2020/3/6
* @Version: 1.0
*/
public class Vegetables extends Price
private Price price;
public Vegetables(Price price)
this.price = price;
@Override
public double getPrice()
return 8.9 + price.getPrice();
/**
* @Author: 欢迎关注公众号:程序员小安
* @description: 豆芽价格(具体装饰者类)
* @CreateDate: 2020/3/6
* @Version: 1.0
*/
public class Sprouts extends Price
private Price price;
public Sprouts(Price price)
this.price = price;
@Override
public double getPrice()
return 4.9 + price.getPrice();
/**
* @Author: 欢迎关注公众号:程序员小安
* @description:金针菇价格(具体装饰者类)
* @CreateDate: 2020/3/6
* @Version: 1.0
*/
public class FlammulinaVelutipes extends Price
private Price price;
public FlammulinaVelutipes(Price price)
this.price = price;
@Override
public double getPrice()
return 6.9 + price.getPrice();
/**
* @Author: 欢迎关注公众号:程序员小安
* @description: 鸭血价格(具体装饰者类)
* @CreateDate: 2020/3/6
* @Version: 1.0
*/
public class DuckBlood extends Price
private Price price;
public DuckBlood(Price price)
this.price = price;
@Override
public double getPrice()
return 11.9 + price.getPrice();
用户点餐类:
/**
* @Author: 欢迎关注公众号:程序员小安
* @description:用户点餐类
* @CreateDate: 2020/3/6
* @Version: 1.0
*/
public class User
public static void main(String[] args)
Price mandarinDuckPrice = new MandarinDuckPrice();//用户选中鸳鸯锅底
mandarinDuckPrice = new Vegetables(mandarinDuckPrice);//用户需要青菜,用Vegetables装饰mandarinDuckPrice
mandarinDuckPrice = new FlammulinaVelutipes(mandarinDuckPrice);//用户需要金针菇,FlammulinaVelutipes装饰mandarinDuckPrice
System.out.println("您需要支付金额为:"+mandarinDuckPrice.getPrice());//输出总金额
运行结果:
您需要支付金额为:103.8
采用装饰者模式后,可以动态的用一个或者多个装饰者装饰对象,比如上面user类中,用DuckBlood,FlammulinaVelutipes装饰MandarinDuckPrice对象。在装饰者内部,比如DuckBlood的getPrice()方法中,我们可以在被装饰对象Price的getPrice()方法前加上DuckBlood自身的价格,达到火锅锅底动态添加配菜,计算总价格的目的。
/**
* @Author: 欢迎关注公众号:程序员小安
* @description:用户点餐类
* @CreateDate: 2020/3/6
* @Version: 1.0
*/
public class User
public static void main(String[] args)
Price mandarinDuckPrice = new MandarinDuckPrice();//用户选中鸳鸯锅底
mandarinDuckPrice = new Vegetables(mandarinDuckPrice);//用户需要青菜,用Vegetables装饰mandarinDuckPrice
mandarinDuckPrice= new Vegetables(mandarinDuckPrice);//用户需要青菜,用Vegetables装饰mandarinDuckPrice
mandarinDuckPrice = new FlammulinaVelutipes(mandarinDuckPrice);//用户需要金针菇,FlammulinaVelutipes装饰mandarinDuckPrice
System.out.println("您需要支付金额为:"+mandarinDuckPrice.getPrice());//输出总金额
运行结果:
您需要支付金额为:112.7
装饰者模式的优点
(1)装饰模式可以提供比继承更多地灵活性。
(2)可以通过一种动态的方式来扩展一个对象的功能,在运行时选择不同的装饰器,从而实现不同的行为。
(3)通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。可以使用多个具体装饰类来装饰同一对象,得到功能更为强大的对象。
(4)具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”。
策略模式的缺点
(1)会产生很多的小对象(具体装饰类),增加了系统的复杂性。
(2)这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。
什么时候使用:
某些业务中,需要动态扩展一个类的行为时优先考虑装饰者模式,因为继承是静态的,无法满足。
微信搜索【程序员小安】“面试系列(java&andriod)”文章将在公众号同步发布。
以上是关于大厂面试必备之设计模式:漫画装饰者模式的主要内容,如果未能解决你的问题,请参考以下文章