裝飾器模式的目的——**核心部分和裝飾部分可以自由組合。** 裝飾器模式要求: - 裝飾可選 - 裝飾可擴展 - 核心部分可擴展 ...
什麼是裝飾器模式?
【先吃三顆慄子:】
1.PC=主機+顯示器+鍵盤+滑鼠+滑鼠墊
主機是核心,而其他的組成部分都是裝飾。
2.手抓餅=餅+雞蛋+培根+黃瓜
餅是核心,雞蛋,培根是可選的,可以理解為裝飾。
3.咖啡=咖啡+牛奶+冰+方糖
咖啡是核心,牛奶等可選。
比喻雖然形象生動,但是與實際或多或少會產生偏差。
抽象的解釋:裝飾器模式的目的——核心部分和裝飾部分可以自由組合。
裝飾器模式的功能
對於軟體開發來說,聚焦於軟體的靈活性和可擴展性。
裝飾器模式要求:
- 裝飾可選
- 裝飾可擴展
- 核心部分可擴展
手抓餅中的裝飾器模式
實現餅加各種配料的價格計算。
思路:
1.定義抽象類手抓餅,其中包含獲取種類的抽象方法和獲取價格的抽象方法。
2.然後定義兩個分別為大份手抓餅和中份手抓餅來繼承這個抽象類,重寫兩個方法定義種類和價格。
3.定義具體的配料類繼承手抓餅抽象類,先定義構造器傳入已經創建的手抓餅種類,然後重寫種類和價格方法。
在網上看的一些博客,是創建出一個抽象的配料類來繼承抽象產品類,然後用具體的配料類來實現抽象配料類,實現裝飾。
可是如果直接將抽象產品類的方法全部定義抽象方法,配料類直接繼承重寫,實現裝飾,功能上也是可以實現的,如下所示,Bacon類直接繼承HandPancake,然後重寫getName和getCost方法,實現裝飾。似乎也沒有問題:
但是設計模式畢竟是一種經驗總結,如果有已經看出端倪的小伙伴們在下方留言交流一下吧!
直接繼承HandPancake:
abstract class HandPancake
{
public abstract String getName();
public abstract int getCost();
}
class HandPancake_Big extends HandPancake
{
@Override
public String getName() {
return "大份手抓餅";
}
@Override
public int getCost() {
return 10;
}
}
class HandPancake_Mid extends HandPancake
{
@Override
public String getName() {
return "中份手抓餅";
}
@Override
public int getCost() {
return 8;
}
}
class Bacon extends HandPancake
{
private HandPancake handPancake;
Bacon(HandPancake handPancake)
{
this.handPancake=handPancake;
}
@Override
public String getName() {
return handPancake.getName()+"加培根";
}
@Override
public int getCost() {
return handPancake.getCost()+1;
}
}
class Cucumber extends HandPancake
{
private HandPancake handPancake;
Cucumber(HandPancake handPancake)
{
this.handPancake=handPancake;
}
@Override
public String getName() {
return handPancake.getName()+"加黃瓜";
}
@Override
public int getCost() {
return handPancake.getCost()+2;
}
}
class Ham extends HandPancake
{
private HandPancake handPancake;
Ham(HandPancake handPancake)
{
this.handPancake=handPancake;
}
@Override
public String getName() {
return handPancake.getName()+"加火腿";
}
@Override
public int getCost() {
return handPancake.getCost()+1;
}
}
public class APPlication
{
public static void main(String[] args) {
HandPancake handPancake_big = new HandPancake_Big();
System.out.println("啥也不加"+handPancake_big.getName()+":"+handPancake_big.getCost());
handPancake_big = new Ham(handPancake_big);
System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
handPancake_big = new Cucumber(handPancake_big);
System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
handPancake_big = new Bacon(handPancake_big);
System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
System.out.println("==============================");
HandPancake handPancake_mid = new HandPancake_Mid();
System.out.println("啥也不加"+handPancake_mid.getName()+":"+handPancake_mid.getCost());
handPancake_mid = new Ham(handPancake_mid);
System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
handPancake_mid = new Cucumber(handPancake_mid);
System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
handPancake_mid = new Bacon(handPancake_mid);
System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
}
}
官方做法:
abstract class HandPancake
{
String name; //1
public String getName()
{
return name;
}
public abstract int getCost();
}
class HandPancake_Big extends HandPancake
{
HandPancake_Big() //2.通過構造器賦值
{
name="大份手抓餅";
}
@Override
public int getCost() {
return 10;
}
}
class HandPancake_Mid extends HandPancake
{
HandPancake_Mid() //2.通過構造器賦值
{
name="中份手抓餅";
}
@Override
public int getCost() {
return 8;
}
}
abstract class Condiments extends HandPancake //3.定義抽象介面
{
public abstract String getName();
}
class Bacon extends Condiments //4.繼承抽象介面
{
private HandPancake handPancake;
Bacon(HandPancake handPancake)
{
this.handPancake=handPancake;
}
@Override
public String getName() {
return handPancake.getName()+"加培根";
}
@Override
public int getCost() {
return handPancake.getCost()+1;
}
}
class Cucumber extends Condiments
{
private HandPancake handPancake;
Cucumber(HandPancake handPancake)
{
this.handPancake=handPancake;
}
@Override
public String getName() {
return handPancake.getName()+"加黃瓜";
}
@Override
public int getCost() {
return handPancake.getCost()+2;
}
}
class Ham extends Condiments
{
private HandPancake handPancake;
Ham(HandPancake handPancake)
{
this.handPancake=handPancake;
}
@Override
public String getName() {
return handPancake.getName()+"加火腿";
}
@Override
public int getCost() {
return handPancake.getCost()+1;
}
}
public class APPlication
{
public static void main(String[] args) {
HandPancake handPancake_big = new HandPancake_Big();
System.out.println("啥也不加"+handPancake_big.getName()+":"+handPancake_big.getCost());
handPancake_big = new Ham(handPancake_big);
System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
handPancake_big = new Cucumber(handPancake_big);
System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
handPancake_big = new Bacon(handPancake_big);
System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
System.out.println("==============================");
HandPancake handPancake_mid = new HandPancake_Mid();
System.out.println("啥也不加"+handPancake_mid.getName()+":"+handPancake_mid.getCost());
handPancake_mid = new Ham(handPancake_mid);
System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
handPancake_mid = new Cucumber(handPancake_mid);
System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
handPancake_mid = new Bacon(handPancake_mid);
System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
}
}
手抓餅的擴展性
- 創建手抓餅的種類
- 創建配料種類
官方的擴展:創建一個小份手抓餅繼承Hanpancake,然後創建配料繼承Condiments。
貼一下直接繼承HandPancake的情況:
class HandPancake_Smalll extends HandPancake
class Egg extends HandPancake
abstract class HandPancake
{
public abstract String getName();
public abstract int getCost();
}
class HandPancake_Big extends HandPancake
{
@Override
public String getName() {
return "大份手抓餅";
}
@Override
public int getCost() {
return 10;
}
}
class HandPancake_Mid extends HandPancake
{
@Override
public String getName() {
return "中份手抓餅";
}
@Override
public int getCost() {
return 8;
}
}
class Bacon extends HandPancake
{
private HandPancake handPancake;
Bacon(HandPancake handPancake)
{
this.handPancake=handPancake;
}
@Override
public String getName() {
return handPancake.getName()+"加培根";
}
@Override
public int getCost() {
return handPancake.getCost()+1;
}
}
class Cucumber extends HandPancake
{
private HandPancake handPancake;
Cucumber(HandPancake handPancake)
{
this.handPancake=handPancake;
}
@Override
public String getName() {
return handPancake.getName()+"加黃瓜";
}
@Override
public int getCost() {
return handPancake.getCost()+2;
}
}
class Ham extends HandPancake
{
private HandPancake handPancake;
Ham(HandPancake handPancake)
{
this.handPancake=handPancake;
}
@Override
public String getName() {
return handPancake.getName()+"加火腿";
}
@Override
public int getCost() {
return handPancake.getCost()+1;
}
}
//========================
class HandPancake_Smalll extends HandPancake
{
@Override
public String getName() {
return "小份手抓餅";
}
@Override
public int getCost() {
return 5;
}
}
class Egg extends HandPancake
{
private HandPancake handPancake;
Egg(HandPancake handPancake)
{
this.handPancake=handPancake;
}
@Override
public String getName() {
return handPancake.getName()+"加雞蛋";
}
@Override
public int getCost() {
return handPancake.getCost()+1;
}
}
public class APPlication
{
public static void main(String[] args) {
HandPancake handPancake_big = new HandPancake_Big();
System.out.println("啥也不加"+handPancake_big.getName()+":"+handPancake_big.getCost());
handPancake_big = new Ham(handPancake_big);
System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
handPancake_big = new Cucumber(handPancake_big);
System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
handPancake_big = new Bacon(handPancake_big);
System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
System.out.println("==============================");
HandPancake handPancake_mid = new HandPancake_Mid();
System.out.println("啥也不加"+handPancake_mid.getName()+":"+handPancake_mid.getCost());
handPancake_mid = new Ham(handPancake_mid);
System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
handPancake_mid = new Cucumber(handPancake_mid);
System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
handPancake_mid = new Bacon(handPancake_mid);
System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
System.out.println("擴展性測試:");
HandPancake handPancake_small = new HandPancake_Smalll();
System.out.println("啥也不加"+handPancake_small.getName()+":"+handPancake_small.getCost());
handPancake_small = new Egg(handPancake_small);
System.out.println(handPancake_small.getName()+":"+handPancake_small.getCost());
}
}
運行結果: