给定增量组合类,如何在只定义一次方法体的同时用一些设计模式实现替换它们?

时间:2014-11-03 17:32:13

标签: c# expandoobject expando

我不认为在这种意义上可以使用设计模式。 案例场景是具有一个基础对象,该对象具有这些属性,并且始终定义相应的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)和三个可选变量的Class的所有可能配置都是2 ^ 3,我想知道是否有办法用设计模式(希望没有Reflection)。请记住,我知道我可以使用更轻松的类型语言或只使用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函数)但是接下来必须再次实现接口中的所有内容:(

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

2 个答案:

答案 0 :(得分:1)

您要找的基本上是c#的dynamic类型和ExpandoObject s。实际上,您可以在运行时将类型构建为您想要的任何类型。

例如:

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。但它实际上只是语言可以支持的东西。不是设计模式。

答案 1 :(得分:0)

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

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