文章出處

一、常量接口模式

在一個軟件系統中會使用一些常量,一種流行的做法就是把相關的常量放在一個專門的常量接口中定義,例如:

public interface MyConstants {
    public static final double MATH_PI = 3.1415926;
    public static final double MATH_E = 2.71828;
 
}

以下Circle類需要訪問以上MATH_PI常量,一種方式是采用直接訪問方式,如下:

public class Circle {
    private double r;//半徑
    public Circle(double r){
        this.r = r;
    }
    public double getCircumference(){
        return 2 * r * MyConstants.MATH_PI;
    }
}

在JDK1.5中引入了”import static“語句,它允許類A直接訪問另一個接口B或類B中的靜態常量,而不必指定接口B或類B的名字,而且類A無須實現接口B或者繼承類B。如下:

import static com.FinalInterface.MyConstants.*;
public class Circle {
    private double r;//半徑
    public Circle(double r){
        this.r = r;
    }
    public double getCircumference(){
        return 2 * r * MATH_PI;
    }
}

import static 語句既可以簡化編程,又能防止Circle類繼承并公開MyConstants中的靜態常量。

二、標識類模式

動物飼養員給貓喂魚,給狗喂骨頭,給老虎喂雞,給熊貓喂竹子,給馬喂草,,這里的魚、骨頭、雞、竹子、草都可以作為動物的食物,因此從中抽象出Food接口。

public interface Food()   //Food接口中沒有任何內容

Food接口不包含任何方法,它僅僅表示一種抽象類型,所有實現該接口的類意味著可以作為食物,例如魚類Fish實現了Food接口,因此它可以作為其他動物的食物

public class Fish extends Animal implments Food(...)

動物飼養員Feeder類的feed()方法的定義如下:

public void feed (Animal animal,Food food){...}

feed方法的food參數為Food類型,表示只能把可作為食物的對象喂給動物,以下程序表示試圖給狗喂書,由于Book類沒有實現Food接口,因此導致編譯錯誤

Book book =new Book();
feeder.feed(dog,book);  //編譯錯誤

如果把feed方法的food參數改為Object類型:

public void feed(Animal animal,Object food){...}

那么就無法借助java編譯器來對傳給feed方法的food參數進行語義上的約束,例如以下程序表示給狗喂一個字符串對象,java編譯器會認為這是合法的

Object anyObject=new String("hello");
feeder.feed(dog,anyObject); //編譯成功

Food接口被稱為標識類型接口,這種接口沒有任何方法,代表一種抽象類型,在JDK中,有如下兩個典型的標識類型接口

① java.io.Serializable接口:實現該接口的類的實例可以被序列化

②java.io.Remote接口:實現該接口的類的實例可以作為遠程對象

三、適配器模式

適配器是兩個接口的中間過度,比如電腦必須要保證電壓在15V,而電源的電壓是220V,則需要一個適配器將220V轉換成15V,因此適配器就是接口的轉換作用。

interface Source{
    public int add(int a,int b);
}
class SourceImpl implements Source{
    public int add(int a,int b){
        return a+b;
    }
}
interface Target{
    public int addOne(int a);
}
class TargetImpl implements Target{
    private Source s ;
    public TargetImpl(Source s){
        this.s = s;
    }
    public int addOne(int a){
        return s.add(a,1);
    }
}
public class AdapterDemo{
    public static void main(String args[]){
        Source s = new SourceImpl();
        Target t = new TargetImpl(s);
        System.out.println("2+1="+t.addOne(2));
    }
}

四、定制服務模式

定制服務的模式也可應用到面向對象的軟件開發領域。當一個系統能對外提供多種類型的服務時,一種方式是粗粒度的接口,把所有的服務放在一個接口中聲明,這個接口臃腫龐大,所有的使用者都訪問同一個接口。還有一種方式就是設計精粒度接口,對服務精心分類,把相關的一組服務放在一個接口中,通過對接口的繼承,可以派生出新的接口,針對使用者的需求提供特定的接口

上表中的極速精英套餐SuperSpeedCombo和金融專網套餐FinanceCombo屬于兩種定制的服務接口,它們可以通過繼承以上5個精粒度的接口而形成,這樣的接口也稱為復合接口。

服務接口定制好以后,接下來的問題是如何實現這些接口。為了提高代碼的可重用性,類的粒度也應該盡可能小,所以首先為精粒度的接口提供實現類。

以下列出其中的一個服務實現類:

 

public class BroadbandServiceImpl implements BroadbandService{
    private int speed;//網速
    public BroadbandServiceImpl(int speed){
        this.speed = speed;
    }
    //連接網絡
    public void connect(String username,String password){...}

    //斷開網絡
    public void disconnect(){...}
}

同上,將精粒度的接口一一創建實現類,得到精粒度的類。

那么對于SuperSpeedCombo 和 FinanceCombo 復合接口,如何實現它們呢?以 SuperSpeedCombo接口的實現類 SuperSpeedComboImpl為例,可以采用組合手段,復用 BroadbandService接口、VirusKillingService接口和MailboxService接口的實現類的程序代碼。

那么什么是組合關系呢?在這再復習一下,所謂的組合和繼承都是提高代碼可重用性的手段,繼承最大的弱點就是破壞封裝,子類和父類之間緊密耦合,子類依賴于父類的實現,子類缺乏獨立性,而組合關系不會破壞封裝,整體類與局部類之間松耦合,彼此相互獨立。當然組合關系也有缺點:創建整體類的對象時需要創建所有局部類的對象,而繼承關系在創建子類的對象時無須創建父類的對象。

比如要在SuperSpeedComboImpl采用組合手段加入寬帶上網服務BroadbandService:

public class SuperSpeedComboImpl implements SuperSpeedCombo{
    private BroadbandServiceImpl BroadbandService;
    public SuperSpeedComboImpl(BroadbandServiceImpl BroadbandService){
        this.BroadbandService = BroadbandService;
    }
}

此外,對于極速精英套餐和金融專網套餐,都有付費方式和價格這些屬性,可以把這些屬性放到同一個Payment中,這符合構建精粒度的對象模型的原則,下面是Payment的源程序:

public class Payment{
    public static final String TYPE_PER_YEAR="按年付費";
    public static final String TYPE_PER_MONTH="按月付費";
    private String type;//付費方式
    private double price;//價格
    public Payment(String type, double price) {
        this.type = type;
        this.price = price;
    }
    //省略type屬性和price屬性的get/set方法
    ...
}

SuperSpeedComboImpl類的源程序如下:

public class SuperSpeedComboImpl implements SuperSpeedCombo{
    private BroadbandServiceImpl BroadbandService;
    private VirusKillingService virusKillingService;
    private MailboxService mailboxService;
    private Payment payment;
    public SuperSpeedComboImpl(BroadbandServiceImpl broadbandService, VirusKillingService virusKillingService,
            MailboxService mailboxService, Payment payment) {
        super();
        BroadbandService = broadbandService;
        this.virusKillingService = virusKillingService;
        this.mailboxService = mailboxService;
        this.payment = payment;
    }
    public BroadbandServiceImpl getBroadbandService() {
        return BroadbandService;
    }
    public void setBroadbandService(BroadbandServiceImpl broadbandService) {
        BroadbandService = broadbandService;
    }
    public VirusKillingService getVirusKillingService() {
        return virusKillingService;
    }
    public void setVirusKillingService(VirusKillingService virusKillingService) {
        this.virusKillingService = virusKillingService;
    }
    public MailboxService getMailboxService() {
        return mailboxService;
    }
    public void setMailboxService(MailboxService mailboxService) {
        this.mailboxService = mailboxService;
    }
    public Payment getPayment() {
        return payment;
    }
    public void setPayment(Payment payment) {
        this.payment = payment;
    }
}

下面創建一個極速精英套餐服務的一個實例:

//創建付費信息,按年付費,價格1555
Payment payment = new Payment(Payment.TYPE_PER_MONTH,1555);

//創建寬帶上網服務,網速2Mbps
BroadbandService broadbandService = new BroadbandServiceImpl(2);

//創建郵箱服務,50MB容量
MailboxService mailboxService = new MialboxServiceImpl(50);

//創建在線殺毒服務
VirusKillingService virusKillingService = new VirusKillingServiceImpl();

//創建極速精英套餐服務
SuperSpeedCombo superSpeedCombo = 
    new SuperSpeedComboImpl(broadbandService,mailboxService,virusKillingService,payment);

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()