0

我不认为在这个意义上可以使用设计模式。案例场景是有一个基础对象,该对象具有这些属性和始终定义的相应 getter/setter:(id、name、content)。除此之外,还有一些具有可选属性和相应的 getter/setter(评论、作者、已删除)的对象。我希望这些对象为 API 提供我所需要的确切属性/方法。

一种方法是将所有内容放在一个状态膨胀的类中

class Article {
    int id;
    int name;
    String content;
    List<Comment> comments;
    Author author;
    bool deleted;

    //getters and setters omitted 
}

另一种是有多个类,但这会导致类名膨胀

class Article {
    int id;
    int name;
    String content;
    //getters and setters omitted 
}


class DeletedArticle : Article {
    bool deleted = true;
    //getters and setters omitted 
}


class ArticleWithAuthor : Article {
    Author author;
    //getters and setters omitted 
}


 class ArticleWithComments : Article {
    List<Comment> comments;
    //getters and setters omitted 
}


 class DeletedArticleWithAuthor : Article {
    bool deleted = true;
    Author author;
    //getters and setters omitted 
 }

 class DeletedArticleWithComments : Article {
    bool deleted = true;
    List<Comment> comments;
    //getters and setters omitted 
 }

 class DeletedArticleWithAuthorAndComments : Article {
    bool deleted = true;
    Author author;
    List<Comment> comments;
    //getters and setters omitted 
 }

 //AND SO ON... 

由于始终具有(id、name、content)和三个可选变量的类的所有可能配置都是 2^3,我想知道是否有办法使用设计模式(希望没有反射)来做到这一点。请记住,我知道我可以使用更轻松的类型语言或仅使用 JSON/XML,但这不是重点:P。此外,如果这完全相关,我也不熟悉部分类(来自 C#)。

正如它所指出的,ExpandoObjects 可能是一种方式。您能否提供一个使用我自己上面的类的示例代码ArticleWithCommentsDeletedArticleWithAuthorAndComments因此不需要定义这些?

因此,例如,ArticleWithComments我想拥有类似的东西

 Article article = new CommentsOnArticle(new Article());

因为DeletedArticleWithAuthorAndComments我想要类似的东西:

 Article article = new AuthorOnArticle(new DeletedOnArticle(new CommentsOnArticle(new Article())));

或其他一些符号,例如:

 Article article = new MergerForArticle();
 article.add(CommentForArticle.class);
 article.add(DeletedForArticle.class);
 article.add(AuthorForArticle.class);

所以换句话说,我想避免定义所有可能的类安排,而只是有一个“动态类声明”

编辑:我也在考虑反射(例如Java Reflect) - 我不知道这是否是一个好习惯......

Edit2:我也在考虑匿名类,并以某种方式将实现作为 lambda 函数传递?(Java现在支持lambda函数)但是接口中的所有东西都必须实现:(

Edit3:有人指出要使用 Expando Objects,所以我相应地更改了问题,因为没有设计模式可以完成这项工作。Java 替代方案可能是:https ://svn.codehaus.org/groovy/branches/gep-3/src/main/groovy/util/Expando.java

4

2 回答 2

1

您正在寻找的基本上是 c# 的dynamic类型和ExpandoObjects。您基本上可以在运行时构建一种类型,使其成为您想要的任何类型。

例如:

class Program
{
    static void Main(string[] args)
    {
        dynamic sampleObject = new ExpandoObject();

        // Create a new event and initialize it with null.
        sampleObject.sampleEvent = null;

        // Add an event handler.
        sampleObject.sampleEvent += new EventHandler(SampleHandler);

        // Raise an event for testing purposes.
        sampleObject.sampleEvent(sampleObject, new EventArgs());
   }

    // Event handler.
    static void SampleHandler(object sender, EventArgs e)
    {
        Console.WriteLine("SampleHandler for {0} event", sender);
    }
}

当然,JavaScript 也有类似的功能,因为您可以在运行时随意在类中添加和删除属性。

这种行为真的可以追溯到 SmallTalk。但这实际上只是语言可以支持的东西。不是设计模式。

于 2014-11-03T19:32:11.020 回答
0

当某种基类型的不同实现可以相互嵌套时,使用装饰器模式,并且在调用方法时,通过调用所有嵌套对象的相同方法来获得方法结果。例如,假设您有一个咖啡课,您还可以在咖啡中添加调味品。单份摩卡可以添加到咖啡或双份摩卡或奶油中。每种调味品都有不同的价格,而且您不知道事先会在咖啡中添加什么调味品。然后你可以使用装饰器模式。您可以用调味品装饰咖啡,当您调用成本方法时,您将获得总成本,即咖啡价格加上所有调味品。(顺便说一下,这个例子来自 Head First Design Patterns 这本书,如果你不这样做,我建议你阅读)

你的情况不是这样的。我认为您可以使用字典。在每个类中,使用适合该类的所有属性初始化字典。

于 2014-11-03T18:33:32.290 回答