0

I don't think a design pattern can be used in this sense. The case scenario is having a base object that has these properties and corresponding getters/setters always defined: (id,name,content). In addition to that there will be objects that have optional properties and corresponding getters/setters (comments, author, deleted). I would like those object to provide the API with the exact properties/methods that I need nothing more and nothing less.

One approach is to have everything in one class which has a bloat of state

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

    //getters and setters omitted 
}

The other one is to have multiple classes but that causes bloat of class Names

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... 

Since all the possible configurations of a Class that always has (id,name,content) and three optional variables is 2^3 I wonder if there is a way to do it with design patterns (hopefully without Reflection). Keep in mind that I know I could use a more relaxed type-wise language or just use JSON/XML but that is not the point :P. Also I am not familiar with partial classes (from C#) if that is relevant at all.

As it was pointed ExpandoObjects could be the way. Could you please provide an example code using my own classes above for ArticleWithComments and DeletedArticleWithAuthorAndComments so these are not needed to be defined ?

So for example for ArticleWithComments I would like to have something like

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

and for DeletedArticleWithAuthorAndComments I would like to have something like:

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

or some other notation like:

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

So in other words I want to avoid defining all the possible arrangements of classes and just have a "dynamic class declaration"

Edit: I was thinking of reflection (e.g Java Reflect) too - I don't know if that would be a good practice though..

Edit2: I was also thinking of Anonymous classes and somehow pass the implementations as lambda functions ?? (Java now supports lambda functions) but then again all of the things in the interface will have to be implemented :(

Edit3: It was pointed to use Expando Objects so I changed the question accordingly since there is no design pattern that does this job. Java alterinative could be : https://svn.codehaus.org/groovy/branches/gep-3/src/main/groovy/util/Expando.java

Michail Michailidis
  • 11,792
  • 6
  • 63
  • 106
  • 2
    I think the closest thing PHP would have to partial classes is [Traits](http://php.net/manual/en/language.oop5.traits.php). I personally don't use them, but perhaps they would be helpful for what you want. To me though it would seem that creating your `Article` class as a domain model would seem better, attach other class collections for things like comments when needed. Also, and this is me nitpicking, is there a such thing as an article without an author? – Crackertastic Nov 03 '14 at 17:42
  • Interesting I will have a look in Traits! The fields are completely made up. It seems that with Traits I still have to define all the classes right? – Michail Michailidis Nov 03 '14 at 17:44
  • @Crackertastic You could think of Article as a DTO object too that doesn't contain Author ;) – Michail Michailidis Nov 03 '14 at 17:58
  • Why don't you just use a dictionary. And Initialize the dictionary with the required state in every class with things that are appropriate for that class. – neo Nov 03 '14 at 18:19
  • In C# you *could* use interfaces. Create 2^3 interfaces, create one class that implements them all. Each action could be an extension method that maps from one interface to another. But I'm not sure I'd recommend it as it doesn't scale to lots of varying properties. – Ian Mercer Nov 03 '14 at 18:58
  • @IanMercer Yeah this bloats the name space of the interfaces now .. so it is the same problem – Michail Michailidis Nov 03 '14 at 19:07

2 Answers2

1

What you are looking for is basically c#'s dynamic types, and ExpandoObjects. You can essentially build up a type at runtime to be whatever you want.

For example:

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);
    }
}

Of course JavaScript has similar functionality too, as you can add and remove properties from classes at runtime at will.

This kind of behavior goes all the way back to SmallTalk really. But it's really only something the language can support. Not a design pattern.

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
0

Decorator pattern is used when different implementations of some base type can be nested in one another and when a method is called, the method result is obtained by calling all nested objects' same method. For example let's say you have a coffee class and you can also add condiments to your coffee. Single Mocha can be added to coffee or Double Mocha or cream. Each condiment has different price and you don't know what condiments would be added to coffee before hand. Then you can use decorator pattern. You can decorate coffee with condiments and when you call cost method, you will get the total cost which means coffee price plus all condiments. (By the way, the example is from Head First Design Patterns book which I recommend reading if you didn't do so)

Your case is not like that. I think you can just use a dictionary. And in each class, initialize the dictionary with all properties that are appropriate for that class.

neo
  • 1,952
  • 2
  • 19
  • 39