1 装饰器模式
星巴克案例
1)咖啡种类/单品咖啡:Espresso(意大利浓咖啡)、ShortBlack、LongBlack(美式咖啡)、Decaf(无因咖啡)
2)调料:Milk、Soy(豆浆)、Chocolate
3)要求在扩展新的咖啡种类时,具有良好的扩展性、改动方便、维护方便
4)使用 OO 的来计算不同种类咖啡的费用: 客户可以点单品咖啡,也可以单品咖啡+调料组合。
Decorator类集成Drink类同时也包含Drink对象(组合关系)
不再是原本的向单品咖啡里面加调味品,而是用调味品一层一层地将单品咖啡包裹起来
public interface Gun {
void fire();
}
public class Pistol implements Gun{
@Override
public void fire() {System.out.println("biu........!");}
}
public class Submachine implements Gun{
@Override
public void fire() {System.out.println("哒哒哒!!!");}
}
public class Kar98K implements Gun{
@Override
public void fire() {System.out.println("砰!,一枪秒人!!!");}
}
// 抽象类,扩容弹夹的一个抽象,继承了Gun接口,可以实现开火功能。
public abstract class AbstractMagazine implements Gun{
private Gun gun;
public AbstractMagazine(Gun gun){this.gun=gun;}
// 继承了某个接口,就必须重写这个接口,但是由于这里一个抽象类,所以接口内容不用实现。
@Override
public void fire() {gun.fire(); }
}
public class Magazine extends AbstractMagazine{
public Magazine(Gun gun) {super(gun);}
@Override
public void fire() {System.out.println("砰,砰,砰,砰,砰.......(Magazine类中的开火情况)");}
}
public interface Aim4X extends Gun{
// 由于枪本身具装弹功能,只是装的数量少,因此,瞄准的接口与弹夹的接口不一样,
// 弹夹接口只是用于扩充数量,而瞄准接口是另一个功能,而要让一个枪具备两个功能,
// 那么继承了瞄准接口的功能的同时,也有开枪功能。
// 所以瞄准接口才要extends 这个Gun接口。而不是implements 这个Gun接口。
void aim4X();
}
// 4倍镜的抽象类,继承自4倍镜接口
// 这里要注意,4倍镜接口的内容,是extends Gun接口,而不是 implements Gun,注意两者的区别。
// 去Aim4X类里去看代码。
public abstract class AbstractTelescope4X implements Aim4X{
private Gun gun;
public AbstractTelescope4X(Gun gun){this.gun=gun;}
@Override
public void fire(){ gun.fire();}
}
public class Telescope4X extends AbstractTelescope4X{
public Telescope4X(Gun gun) { super(gun);}
// 继承自抽象类,抽象类继承自接口,接口里面有这个功能,
// 所以接口继承接口时不用写,形成的抽象类也不用写,但在这里是具体类的实现,就要写,而且是重写。
@Override
public void aim4X() {System.out.println("启用4倍镜瞄准模式," +
"看的更清,打的更准!(Telescope4X类里的瞄准函数。)");}
}
public class Main {
public static void main(String[] args) {
// write your code here
System.out.println("[生成一把手枪:]");
Gun gun1 = new Pistol();
System.out.println("[打个手枪:]");
gun1.fire();
System.out.println("..........................................................");
System.out.println("[生成一把冲锋枪:]");
Gun gun2 = new Submachine();
System.out.println("[准备扫射.......]");
gun2.fire();
System.out.println("..........................................................");
System.out.println("[捡起一把98K]");
Gun gun = new Kar98K(); // 注意这里,它和 Kar98K gun = new Kar98K(); 有什么区别?
System.out.println("[瞄准头部.......]");
gun.fire();
System.out.println("..........................................................");
//只给98K装上4倍镜
System.out.println("[装饰上4倍镜]");
Aim4X aim4X = new Telescope4X(gun);
System.out.println("[4倍瞄准]");
aim4X.aim4X();
System.out.println("[装上4倍镜后的98K!]");
aim4X.fire();
System.out.println("..........................................................");
//只给98K装上扩容弹夹
System.out.println("[装饰上弹匣]");
gun = new Magazine(gun);
System.out.println("[扩容后的98K]");
gun.fire();
System.out.println("..........................................................");
//同时装弹夹和4倍镜,看看开枪效果
System.out.println("[先装饰上弹匣]");
gun = new Magazine(gun);
System.out.println("[已扩充弹夹的98K...]");
System.out.println("[再装饰上4倍镜]");
aim4X = new Telescope4X(gun);
System.out.println("[已安装4倍镜的98k...]");
aim4X.aim4X();
System.out.println("[开启了4倍镜的98K...]");
System.out.println("[狙击枪扩充和弹夹和使用了4倍镜的情况下!...]");
aim4X.fire();
}
}