2017-05-03 70 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)