04、 接口在應用中常見的三種模式
在程式設計領域,好的設計模式能夠讓我們的代碼事半功倍。在使用接口的時候,經常會用到三種模式,分别是政策模式、擴充卡模式和工廠模式。
1)政策模式
政策模式的思想是,針對一組算法,将每一種算法封裝到具有共同接口的實作類中,接口的設計者可以在不影響調用者的情況下對算法做出改變。示例如下:
// 接口:教練
interface Coach {
// 方法:防守
void defend();
}
// 何塞·穆裡尼奧
class Hesai implements Coach {
@Override
public void defend() {
System.out.println("防守赢得冠軍");
}
}
// 德普·瓜迪奧拉
class Guatu implements Coach {
@Override
public void defend() {
System.out.println("進攻就是最好的防守");
}
}
public class Demo {
// 參數為接口
public static void defend(Coach coach) {
coach.defend();
}
public static void main(String[] args) {
// 為同一個方法傳遞不同的對象
defend(new Hesai());
defend(new Guatu());
}
}
Demo.defend() 方法可以接受不同風格的 Coach,并根據所傳遞的參數對象的不同而産生不同的行為,這被稱為“政策模式”。
2)擴充卡模式
擴充卡模式的思想是,針對調用者的需求對原有的接口進行轉接。生活當中最常見的擴充卡就是HDMI(英語:High Definition Multimedia Interface,中文:高清多媒體接口)線,可以同時發送音頻和視訊信号。擴充卡模式的示例如下:
interface Coach {
void defend();
void attack();
}
// 抽象類實作接口,并置空方法
abstract class AdapterCoach implements Coach {
public void defend() {};
public void attack() {};
}
// 新類繼承擴充卡
class Hesai extends AdapterCoach {
public void defend() {
System.out.println("防守赢得冠軍");
}
}
public class Demo {
public static void main(String[] args) {
Coach coach = new Hesai();
coach.defend();
}
}
Coach 接口中定義了兩個方法(defend() 和 attack()),如果類直接實作該接口的話,就需要對兩個方法進行實作。
如果我們隻需要對其中一個方法進行實作的話,就可以使用一個抽象類作為中間件,即擴充卡(AdapterCoach),用這個抽象類實作接口,并對抽象類中的方法置空(方法體隻有一對花括号),這時候,新類就可以繞過接口,繼承抽象類,我們就可以隻對需要的方法進行覆寫,而不是接口中的所有方法。
3)工廠模式
所謂的工廠模式了解起來也不難,就是什麼工廠生産什麼,比如說寶馬工廠生産寶馬,奔馳工廠生産奔馳,A 級學院畢業 A 級教練,C 級學院畢業 C 級教練。示例如下:
// 教練
interface Coach {
void command();
}
// 教練學院
interface CoachFactory {
Coach createCoach();
}
// A級教練
class ACoach implements Coach {
@Override
public void command() {
System.out.println("我是A級證書教練");
}
}
// A級教練學院
class ACoachFactory implements CoachFactory {
@Override
public Coach createCoach() {
return new ACoach();
}
}
// C級教練
class CCoach implements Coach {
@Override
public void command() {
System.out.println("我是C級證書教練");
}
}
// C級教練學院
class CCoachFactory implements CoachFactory {
@Override
public Coach createCoach() {
return new CCoach();
}
}
public class Demo {
public static void create(CoachFactory factory) {
factory.createCoach().command();
}
public static void main(String[] args) {
// 對于一支球隊來說,需要什麼樣的教練就去找什麼樣的學院
// 學院會介紹球隊對應水準的教練。
create(new ACoachFactory());
create(new CCoachFactory());
}
}
有兩個接口,一個是 Coach(教練),可以 command()(指揮球隊);另外一個是 CoachFactory(教練學院),能 createCoach()(教出一名優秀的教練)。然後 ACoach 類實作 Coach 接口,ACoachFactory 類實作 CoachFactory 接口;CCoach 類實作 Coach 接口,CCoachFactory 類實作 CoachFactory 接口。當需要 A 級教練時,就去找 A 級教練學院;當需要 C 級教練時,就去找 C 級教練學院。
依次類推,我們還可以用 BCoach 類實作 Coach 接口,BCoachFactory 類實作 CoachFactory 接口,進而不斷地豐富教練的梯隊。
05、 總結
盡管接口使得抽象更進一步,但任何抽象性都應該根據真正的需求而産生,是以恰當的原則是優先選擇類而不是接口,隻有在真正需要接口的時候再重構代碼。