《魂鬥羅歸來》之代理模式VS裝飾模式

YoungManSter發表於2019-02-28

歡迎收看俗到掉渣的《小Y講堂》節目,大家好,我是小Y,一個集性感毛髮與才華於一身的程式猿。小Y的設計模式系列中的**「代理模式」「裝飾模式」**在前面已經總結過了,又是時候嘮叨嘮叨這兩者之間在《魂鬥羅歸來》中的是是非非了。

一、模式介紹

1.通用UML的對比

《魂鬥羅歸來》之代理模式VS裝飾模式

從上圖可以看到,代理模式和裝飾模式的類圖非常類似,裝飾模式可以說是代理模式的一個特殊應用,兩者的共同點是都具有相同的介面。

2.模式的介紹

  • 代理模式,為其他物件提供一種代理以控制物件的訪問。
  • 裝飾模式,動態地給物件新增一些額外的職責,可以通過使用不同的具體裝飾類以及這些裝飾類的排列組合,創造出很多不同行為的組合。

### 小Y,你搞什麼呀?都嘮叨老半天了,怎麼還不進入正題呀,區別區別!!!

### 客官,別急別急,小Y馬上帶你去爽爽...千萬別想歪,我們是要幹正事的!!我們的叼煙大漢比爾·雷澤馬上就要跟大家見面。

二、代理模式下比爾·雷澤的武器輸出

1.代理模式下武器輸出的UML

《魂鬥羅歸來》之代理模式VS裝飾模式

2.代理模式下武器輸出的程式碼實現

①武器輸出介面類

 public interface IWeapon {
	void output();
}
複製程式碼

②打小兵選擇G5手雷輔助攻擊

public class PlayCreeps implements IWeapon {

	@Override
	public void output() {
    	System.out.print("散彈槍進行掃射!G5手雷輔助攻擊!");
	}
}
複製程式碼

③打大機選擇集速手雷輔助

public class PlayBigMachine implements IWeapon {
	@Override
	public void output() {
    	System.out.print("散彈槍進行掃射!集速手雷輔助!");
	}
}
複製程式碼

④小Y代理

public class 小Y_Proxy implements IWeapon {

	private IWeapon weapon;
	public 小Y_Proxy(IWeapon weapon) {
    	this.weapon=weapon;
	}

	@Override
	public void output() {
    	weapon.output();
	}
}
複製程式碼

⑤Client實現

public class Client {
	public static void main(String[] args){

    	//打小兵使用G5手雷輔助
    	PlayCreeps playCreeps=new PlayCreeps();
    	小Y_Proxy 小Y_proxy=new 小Y_Proxy(playCreeps);
    	小Y_proxy.output();
    	//打大機使用集速手雷輔助
    	PlayBigMachine playBigMachine=new PlayBigMachine();
    	小Y_Proxy 小Y_proxy1=new 小Y_Proxy(playBigMachine);
    	小Y_proxy1.output();
	}
}
複製程式碼

輸出的結果為:

①散彈槍進行掃射!G5手雷輔助攻擊!
②散彈槍進行掃射!集速手雷輔助!
複製程式碼

從實現程式碼中可以看出,在不改變介面的前提下,對武器輸出進行控制。比爾·雷澤用什麼武器有小Y決定的,小Y讓比爾·雷澤攜帶打小兵型武器他就得帶,小Y對比爾·雷澤的武器輸出有絕對的控制權。

三、裝飾模式下比爾·雷澤的武器輸出

1.裝飾模式下武器輸出類圖

《魂鬥羅歸來》之代理模式VS裝飾模式

2.裝飾模式下武器輸出的程式碼實現

①武器輸出介面類

public interface IWeapon {
	void output();
}
複製程式碼

②武器輸出裝飾抽象類

public abstract class PlayDecorator implements IWeapon {
	private IWeapon weapon;

	public PlayDecorator(IWeapon weapon) {
   	 	this.weapon = weapon;
	}
	@Override
 	public void output() {
    	weapon.output();
	}
}
複製程式碼

③打小兵使用G5手雷輔助攻擊

public class PlayCreeps extends PlayDecorator {
	public PlayCreeps(IWeapon weapon) {
		super(weapon);
	}

	@Override
	public void output() {
		super.output();
		System.out.print("G5手雷輔助攻擊!");
	}
}
複製程式碼

④打大機使用集速手雷輔助

public class PlayBigMachine extends PlayDecorator {
	public PlayBigMachine(IWeapon weapon) {
    	super(weapon);
 	}

	@Override
	public void output() {
    	super.output();
    	System.out.print("集速手雷輔助!");
	}
}
複製程式碼

⑤實現角色比爾·雷澤(對它進行裝飾)

public class BillRizer implements IWeapon {
	@Override
	public void output() {
    	//角色最基本的技能
    	System.out.print("散彈槍進行掃射!");
	}
}
複製程式碼

⑥Client實現

public class Client {
	public static void main(String[] args){
    	//需要裝飾的BillRizer
   		BillRizer billRizer=new BillRizer();
    	//打小兵使用G5手雷輔助
    	PlayCreeps playCreeps=new PlayCreeps(billRizer);
    	playCreeps.output();
    	//打大機使用集速手雷輔助
    	PlayBigMachine playBigMachine=new PlayBigMachine(playCreeps);
    	playBigMachine.output();
 	}
}
複製程式碼

輸出的結果為:

①散彈槍進行掃射!G5手雷輔助攻擊!
②散彈槍進行掃射!G5手雷輔助攻擊!集速手雷輔助!
複製程式碼
  • 裝飾類對被裝飾類的行為沒有決定權,只有加強作用,它不決定被代理的方法是否被執行,只是起到增強或者減弱被代理的功能。比爾·雷澤的武器輸出並不固定,在輸出的過程中還可以通過組合確定。
  • 裝飾模式的本質是動態組合。每個裝飾類負責新增一些額外的功能,然後通過組合為被裝飾類新增負複雜功能,每個裝飾類的職責比較簡單,增加可重用性,符合單一職責原則。

三、小結

  • 代理模式目標是控制對被代理物件的訪問,把當前的行為或功能委託給其他物件執行,不對被代理物件做任何的處理,負責介面限定;裝飾模式是在要保證介面不變的情況下加強類的功能,保證的是被裝飾的物件功能比原始的豐富或者減弱。
  • 代理類所代理的類的行為完全由代理類確定;裝飾模式的物件需要根據實際組合來確定。

Android技術交流吧

相關文章