装饰器模式
结构型模式:关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式
装饰器模式属于结构型模式的一种
装饰器模式:允许向一个现有的对象添加新的功能,同时又不改变其结构。
场景:
奶茶的种类有很多种,比如有巧克力奶茶,QQ奶茶,茉香奶茶等;
然而奶茶中又可以加珍珠,红豆,布丁等不同的甜品。
奶茶店现在要卖各种口味的奶茶,如果不使用装饰模式,那么在销售系统中,各种不一样的奶茶都要产生一个类,如果有5种奶茶类,5种甜品,那么就会产生至少25个类(不包括混合口味)
如果使用了装饰模式,那么几个类就可以搞定了
话不多说,制作两杯奶茶体会一下吧
制作过程:
主要分五步:
1、创建基本奶茶种类接口类(MilkTea)
2、继承基本奶茶接口(MilkTea),创建两个具体的奶茶类:巧克力奶茶(ChocolateMT),QQ奶茶(QQMT)
3、创建实现奶茶种类接口的奶茶装饰类(Decorator)
4、创建继承奶茶装饰类(Decorator)的具体装饰类即加料类:珍珠(Pearl)、布丁(Pudding)
5、创建奶茶订单(MilkTeaOrder)开始制作奶茶
1、创建基本奶茶种类接口类
/**1、创建基本奶茶种类接口类
* 基本奶茶的种类描述、价钱
*/
public interface MilkTea {
String type();
Double price();
}
2、继承基本奶茶接口,创建两个具体的奶茶类
/**
* 2、创建两个具体的奶茶类:巧克力奶茶,QQ奶茶
*
* 继承奶茶接口,具体奶茶类:巧克力奶茶
*/
public class ChocolateMT implements MilkTea{
private String type = "巧克力奶茶";
@Override
public String type() {
//奶茶名称就是定义的属性:巧克力奶茶
return type;
}
@Override
public Double price() {
//巧克力奶茶价格
return 10.00;
}
}
/**
* 2、创建两个具体的奶茶类:巧克力奶茶,QQ奶茶
* 继承奶茶接口,具体奶茶类:qq奶茶
*/
public class QQMT implements MilkTea{
private String type = "QQ奶茶";
@Override
public String type() {
//奶茶名称就是定义的属性:qq奶茶
return type;
}
@Override
public Double price() {
//qq奶茶价格
return 8.00;
}
}
3、创建实现奶茶种类接口的奶茶装饰类
/**
* 3、创建实现奶茶种类接口的装饰类
*
* 创建奶茶种类的装饰类Decorator,让加料类继承装饰类
*/
public class Decorator implements MilkTea{
private String type = "我只是装饰器,不知道是哪种奶茶";
@Override
public String type() {
return null;
}
@Override
public Double price() {
//价格由种类来决定
return 0.00;
}
}
4、创建继承奶茶装饰类的具体装饰类即加料类
/**4、创建具体装饰类即加料类
*
*
* 加料类继承奶茶装饰类
*
* 具体装饰类:给奶茶的料,加入珍珠
*/
public class Pearl extends Decorator{
//加的料名
private String pearl = "+珍珠";
//珍珠的价格
private Double pearlprice = 3.00;
//珍珠加在哪种奶茶里
private MilkTea milkTea = null;
//有参构造器,将订单制作的奶茶参数赋值传递给该类定义的属性milkTea,它是MilkTea类可以调用MilkTea类的属性从而达到描述叠加、价钱叠加
public Pearl(MilkTea milkTea) {
this.milkTea = milkTea;
}
@Override
public String type() {
//奶茶描述叠加
return milkTea.type() + pearl;
}
@Override
public Double price() {
//奶茶价钱叠加
return milkTea.price() + pearlprice;
}
}
/**
* 4、创建具体装饰类即加料类
*
* 加料类继承装饰类
* 具体装饰类:给奶茶的料,加入布丁
*/
public class Pudding extends Decorator{
//加的料名
private String pudding = "+布丁";
//布丁的价格
private Double puddingprice = 4.00;
//布丁加在哪种奶茶里
private MilkTea milkTea = null;
//有参构造器,将订单制作的奶茶参数赋值传递给该类定义的属性milkTea,它是MilkTea类可以调用MilkTea类的属性从而达到描述叠加、价钱叠加
public Pudding(MilkTea milkTea) {
this.milkTea = milkTea;
}
@Override
public String type() {
//奶茶描述叠加
return milkTea.type() + pudding;
}
@Override
public Double price() {
//价钱叠加
return milkTea.price() + puddingprice;
}
}
5、创建奶茶订单开始制作奶茶,下午茶时间到了,想喝什么奶茶随便点,老板请客~~
/**
* 5、奶茶订单
*/
public class MilkTeaOrder {
public static void main(String[] args) {
//订单1:一杯巧克力奶茶+布丁+珍珠
//制作巧克力奶茶
MilkTea chocolateMT = new ChocolateMT();
//+布丁
chocolateMT = new Pudding(chocolateMT);
//+珍珠
chocolateMT = new Pearl(chocolateMT);
System.out.println("订单1小票:");
System.out.println("点餐:" + chocolateMT.type() );
System.out.println("合计:"+ chocolateMT.price() );
System.out.println("-----------------------------");
//订单2:一杯QQ奶茶+珍珠
//制作qq奶茶
MilkTea qqmt = new QQMT();
//+珍珠
qqmt = new Pearl(qqmt);
System.out.println("订单2小票:");
System.out.println("点餐:" + qqmt.type());
System.out.println("合计:" + qqmt.price());
}
}
6、收好小票,拿回去给boss报销
订单1小票:
点餐:巧克力奶茶+布丁+珍珠
合计:17.0
-----------------------------
订单2小票:
点餐:QQ奶茶+珍珠
合计:11.0
总结:
嘿嘿终于实现奶茶加料自由了,装饰器模式总结,完结撒花~~