2017-08-16 48 views
4

我有一個關於OOP實現和設計模式的問題。要使用哪種設計模式(如果存在)?

我有一個固定的類模型,我不能改變(因爲它是每次應用程序啓動時自動生成的)。在這裏有很多類和類似的字段,如下面的例子:你可以看到字段citystreets包含在兩個類中。

public class A{ 
    String city; 
    String street; 

    String name; 

    ....//get methods 
} 

public class B{ 
    String city; 
    String street; 

    String age; 

    ....//get methods 
} 

我需要提取地址形成兩種類型的課程,我想用一個方法來實現它(因爲它似乎是愚蠢的,兩次寫相同的代碼)。如果班級模型是可變的,我可以添加一個新的界面Addressable,其中AB可以實現。

public interface Addressable{ 

    public String getStreet(); 
    public String getCity(); 
} 

//somewhere in code 
public Address getAddress(Addressable addressable){ 
     return new Address(addressable.getCity(), addressable.getStreet()); 
} 

什麼是最優雅的方式來實現相同的沒有接口,並沒有編碼相同的不同的類?

+1

目前尚不清楚在A和B中你實際可以改變什麼。 – davidxxx

+0

沒有優雅的方法,你可以嘗試轉換到合適的類,或者使用反射(對於這種需要可能太重)。 –

+0

如果這些類不能被改變(如果它們是可能被生成的),並且你不能爲那些實現了一個通用接口的類生成包裝器/裝飾器,否則我會看到的唯一方法就是反射。但在走下這條路線之前,我會認真思考如果沒有反思,可以做些什麼。生成(或至少填充)這些包裝的一種方法可能是[mapstruct](http://mapstruct.org/)。 – Thomas

回答

3

如果您無法更改A或B,您將必然會遇到降級解決方案。
一個簡單而好的設計解決方案當然會依賴定義一個地址檢索方法(Address getAddress())的接口,AB將實現。

你也可以定義一個包裝類:

public class WrapperA implements Addressable { 

    private final A a; 

    public WrapperA(A a) { 
    this.a = a; 
    } 

    @Override 
    public Address getAddress(){ 
    return new Address(a.getCity(), a.getStreet(), etc...); 
    } 

} 

但如果你有重複這種代碼許多類可能是相當笨拙。
除了客戶端不會再操作A而是WrapperA類。
它可能會破壞實際的客戶端代碼。
所以在這裏,如果你想實現一個真正的適配器,則需要一個接口。

如上所述,如果不重新設計最小值AB,那麼一個非常好的解決方案很複雜。


至於解決方法,你可以定義一個Address類,它提供的工廠方法來創建從AB實例Address

public class Address{ 

    ... 
    String city; 
    String street; 
    ... 

    private Address(){ 
    } 

    public static Address of(A a){ 
    return new Address(a.getStreet(), a.getCity(), ....); 
    } 

    public static Address of(B b){ 
    return new Address(b.getStreet(), b.getCity(), ...); 
    } 

} 

然後使用這些方法在需要時根據需要創建地址。

0

我有類似的情況,在構建過程中生成類。 (在我的情況下,構建過程將檢查數據庫,併爲每個數據庫表生成一個包含所有字段的類。)

您聲明這些類是在應用程序啓動時生成的。如果它們是在構建過程中生成的,則可以在構建過程中添加一個額外的元素,以改變genreated文件。在我的情況下,我們的構建服務器只有Linux,所以我在我們的ant腳本中添加了sed行。

2

你可以寫adapters來提供一個通用接口。

public class AdpaterA implements Addressable { 

    private final A a; 

    public AdapterA(A a) { 
    this.a = a; 
    } 

    @Override public String getStreet() { 
    return this.a.street; 
    } 

    // other method is omitted as homework ;-) 
} 

然後,您將使用適配器類進行進一步處理。

相關問題