2017-05-03 73 views
0

來自OOP範例和從OOP語言移植代碼,我遇到了一個問題,現在通過抽象在OOP中解決,所以我想知道如何處理下面的問題在Go下面的組合而不是繼承。子類型超類型去

在這種情況下,我的ValueObjects(DTO,POJO等)由其他ValueObjects組成。我通過返回json的Web服務調用來填充它們,所以基本上我的函數/方法調用對於所有類型和子類型都是通用的。

我的超類型EntityVO

type EntityVO struct { 
    EntityName string 
    EntityType string 
    PublicationId string 
    Version  string 
} 

與EntityVO

type ArticleVO struct { 
    EntityVO 
    ContentSize string 
    Created  string 
} 

與EntityVO有它自己的一套獨特的領域

type CollectionVO struct { 
    EntityVO 
    ProductId string 
    Position string 
} 

我組成的亞型2組成的亞型1調用Web服務來檢索數據並填充這些VO。

早些時候,我有一個函數調用Web服務和填充數據,但現在我複製每個VO的代碼。

type Article struct{} 

func (a *Article) RequestList(articleVO *valueObject.ArticleVO) (*valueObject.ArticleVO, error) { 
    // some code 
} 

複製相同的代碼,但更改簽名。

type Collection struct{} 

func (c * Collection) RequestList(collectionVO *valueObject.CollectionVO) (*valueObject.ArticleVO, error) { 
    // some code - duplicate same as above except method signature 
} 

和我有幾個實體,只是因爲我的VO的是不同的,我不得不重複的代碼,並照顧到每一類VO我所。在OOP中,子類型可以傳遞給一個接受超類型的函數,但不能傳入,所以想知道應該如何實現,因此我不會得到重複的代碼,這些代碼在簽名中只有不同的地方?

對於這種情況下的更好方法有何建議?

回答

1

這是golang接口可以發光。

但值得注意的是,在golang中編寫子類/繼承代碼很困難。我們寧願把它當作構圖。

type EntityVO interface { 
    GetName() string 
    SetName(string) error 
    GetType() string 
    ... 
} 

type EntityVOImpl struct { 
    EntityName string 
    EntityType string 
    PublicationId string 
    Version  string 
} 

func (e EntityVOImpl) GetName() string { 
    return e.EntityName 
} 

... 

type ArticleVOImpl struct { 
    EntityVOImpl 
    ContentSize string 
    Created  string 
} 

type CollectionVOImpl struct { 
    EntityVO 
    ProductId string 
    Position string 
} 

// CODE 

func (e *Entity) RequestList(entityVO valueObject.EntityVO) (valueObject.EntityVO, error) { 
    // some code 
} 

另外,只要你的接口文件是共享的,我不認爲應該有任何問題發送/編組/解組在導線的結構。

+0

這聽起來很有希望,我現在按照應該的方式繼續進行這個項目,如果有問題的話,我們很快會回來。 – user2727195

1

json.Unmarshal的第二個參數是「通用」interface{}類型。我認爲類似的方法適用於你的情況。

  1. 定義用於存儲對於每個實體可能不同的web服務屬性的數據類型,例如,

    type ServiceDescriptor struct { 
        URI string 
        //other field/properties... 
    } 
    
  2. 功能用於填充實體可能看起來像

    func RequestList(desc *ServiceDescriptor, v interface{}) error { 
        //Retrieve json data from web service 
        //some code 
    
        return json.Unmarshal(data, v) 
    } 
    
  3. 你可以調用函數來填充不同類型的實體,例如中

    desc := &ServiceDescriptor{} 
    
    article := ArticleVO{} 
    desc.URI = "article.uri" 
    //... 
    //You must pass pointer to entity for 2nd param 
    RequestList(desc, &article) 
    
    collection := CollectionVO{} 
    desc.URI = "collection.uri" 
    //... 
    //You must pass pointer to entity for 2nd param 
    RequestList(desc, &collection)