1. 程式人生 > >由淺入深——Java關於增強類功能的幾種方法

由淺入深——Java關於增強類功能的幾種方法

       今天就Java語言中關於類功能方法增強這一塊的內容進行了梳理與整理。便藉此PO出自己的第一篇關於技術方面的博文,將自己的所學,所思,所感碼出來,是分享,亦是學習。

       這裡所提到的方法增強就是通過Java的一些特性來對一個類的功能進行豐富與增強,便於對現有的專案進行擴充套件。這裡主要介紹3種方法,即繼承或實現介面類、裝飾者模式和動態代理。首先從基礎的概念入手:

繼承

是面向物件最顯著的一個特性。在Java中,類的繼承是指在一個現有類的基礎上去構建一個新的類,構建出來的新類被稱作子類,現有類被稱作父類,子類會自動擁有父類所有可繼承的屬性和方法。繼承是從已有的類中派生出新的類,新的類能吸收已有類的資料屬性和行為,並能擴充套件新的能力。

裝飾者模式

即Decorator模式(別名Wrapper)指的是在不必改變原類檔案和使用繼承的情況下,動態地擴充套件一個物件的功能。它是通過建立一個包裝物件,也就是裝飾來包裹真實的物件。

動態代理 

即Proxy Pattern,23種常用的面向物件軟體的設計模式之一。為其他物件提供一種代理以控制對這個物件的訪問。在某些情況下,一個物件不適合或者不能直接引用另一個物件,而代理物件可以在客戶端和目標物件之間起到中介的作用。

在對三者的概念有了初步的瞭解和認知的前提下,在分別介紹每個手段的特性。

===========繼  承===========

java是面向物件的語言,繼承機制使他的可擴充套件性大大增強,我們可以通過繼承方式對現有類進行擴充套件增強。子類繼承父類之後可以獲得父類所有的公共方法,子類可以進行重寫等操作,這種方式簡便易學,但是隨之而來的是程式碼的耦合性大大的增強,不利於後期的維護,所以對於繼承這種方法,謹慎使用。

class Fu{
	public void show(){
		System.out.println("Fu類中的show方法執行");
	}
}
class Zi extends Fu{
	public void show2(){
		System.out.println("Zi類中的show2方法執行");
	}
}
public  class Test{
	public static void main(String[] args) {
		Zi z = new Zi();
		z.show(); //子類中沒有show方法,但是可以找到父類方法去執行
		z.show2();
	}
}

當在程式中通過物件呼叫方法時,會先在子類中查詢有沒有對應的方法,若子類中存在就會執行子類中的方法,若子類中不存在就會執行父類中相應的方法。

============裝飾者模式===========

設計原則:

1. 多用組合,少用繼承。

      利用繼承設計子類的行為,是在編譯時靜態決定的,而且所有的子類都會繼承到相同的行為。然而,如果能夠利用組合的做法擴充套件物件的行為,就可以在執行時動態地進行擴充套件。

2. 類應設計的對擴充套件開放,對修改關閉。

要點:

1. 裝飾者和被裝飾物件有相同的超型別。

2. 可以用一個或多個裝飾者包裝一個物件。

3. 裝飾者可以在所委託被裝飾者的行為之前或之後,加上自己的行為,以達到特定的目的。

4. 物件可以在任何時候被裝飾,所以可以在執行時動態的,不限量的用你喜歡的裝飾者來裝飾物件。

5. 裝飾模式中使用繼承的關鍵是想達到裝飾者和被裝飾物件的型別匹配,而不是獲得其行為。

6. 裝飾者一般對元件的客戶是透明的,除非客戶程式依賴於元件的具體型別。在實際專案中可以根據需要為裝飾者新增新的行為,做到“半透明”裝飾者。

7. 介面卡模式的用意是改變物件的介面而不一定改變物件的效能,而裝飾模式的用意是保持介面並增加物件的職責。

實現步驟:

1.裝飾者類和被裝飾者類必須實現同一個介面,或繼承同一個類
2.在裝飾者類中,必須要有被裝飾者類的引用
3.在裝飾者類中對需要增強的方法,進行增強
4.在裝飾者類中對不需要增強的方法,呼叫原來的業務邏輯

舉個例子深入理解一下,

   周霆

裝飾模式為已有類動態附加額外的功能就像LOL、王者榮耀等類Dota遊戲中,英雄升級一樣。每次英雄升級都會附加一個額外技能點學習技能。具體的英雄就是ConcreteComponent,技能欄就是裝飾器Decorator,每個技能就是ConcreteDecorator;

//Component 英雄介面 publicinterfaceHero{//學習技能void learnSkills();}//ConcreteComponent 具體英雄盲僧publicclassBlindMonkimplementsHero{privateString name;publicBlindMonk(String name){this.name = name;}@Overridepublicvoid learnSkills(){System.out.println(name +"學習了以上技能!");}}//Decorator 技能欄publicclassSkillsimplementsHero{//持有一個英雄物件介面privateHero hero;publicSkills(Hero hero){this.hero = hero;}@Overridepublicvoid learnSkills(){if(hero !=null)
            hero.learnSkills();}}//ConreteDecorator 技能:QpublicclassSkill_QextendsSkills{privateString skillName;publicSkill_Q(Hero hero,String skillName){super(hero);this.skillName = skillName;}@Overridepublicvoid learnSkills(){System.out.println("學習了技能Q:"+skillName);super.learnSkills();}}//ConreteDecorator 技能:WpublicclassSkill_WextendsSkills{privateString skillName;publicSkill_W(Hero hero,String skillName){super(hero);this.skillName = skillName;}@Overridepublicvoid learnSkills(){System.out.println("學習了技能W:"+ skillName);super.learnSkills();}}//ConreteDecorator 技能:EpublicclassSkill_EextendsSkills{privateString skillName;publicSkill_E(Hero hero,String skillName){super(hero);this.skillName = skillName;}@Overridepublicvoid learnSkills(){System.out.println("學習了技能E:"+skillName);super.learnSkills();}}//ConreteDecorator 技能:Rpublicclass