简体   繁体   中英

Is Composition pattern good choice in this scenario?

Here is one design dilemma I have...

In my program, I have different kind of entries - numeric, textual, date, image, etc.

My first idea was to have model structured with inheritance like this:

Entry 
    -- NumericEntry (extends Entry)
    -- TextualEntry (extends Entry)
    -- DateEntry (extends Entry)
    -- ImageEntry (extends Entry)

Then I can have a list of Entry objects, and each object will know how to handle & expose its data through common members (ie showData(), makeSummary() etc.) If I want to add new Entry object, I will just add another class with that specific type.

But, java limitations, and also android orm libraries limitations makes this pretty complicated.

So, I have turned to composite pattern, but I am not sure if I am approaching it right.

So, now I have this (pseudocode):

 class Entry
    {
    Type type;
    (nullable)NumericEntry  numericEntry;
    (nullable)TextualEntry textualEntry;
    (nullable)DateEntry dateEntry;
    (nullable)ImageEntry imageEntry;

    public showData() 
    { 
        swicth (type) 
        {
          case numeric: ..
          case textual: ..
          case date: ..
          case image: ..
         }
    }
}

But this seems to me too wired, doesn't it? What would be right approach in the described scenario?

I think what you're trying to do is legit, but I think the composite pattern is a bit off here. The composite pattern is rather used for hierarchical structures, as far as I know (like directory structures).

Your model seems quite good, using an (abstract) base class, and let the other types extend from it, however I fail to understand why you want to have all the different types of entries in your base Entry class.

If I understand correctly what you want then this would be more logical.

Interface example:

public interface Entry{
    // Define all your methods as abstract and define them here
    void showData();
}

public class TextualEntry implements Entry{
     void showData(){
         // Your implementation for textual entries here
     }
}
// Repeat this for the other types of entries

You could also consider an abstract class implementation, which can define properties/fields used in all the extended classes. Moreover, you can implement methods in the abstract class which have the same implementation for all extended classes.

Abstract class example:

abstract class Entry{
    // Define your properties here that are used in all the other classes

    // Define all your methods as abstract and define them here
    public abstract void showData();
}

class TextualEntry extends Entry{
     // Define new properties here

     public override void showData(){
         // Your implementation for textual entries here
     }
}
// Repeat this for the other types of entries

On http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html they discuss a similar problem.

If I understand your request correctly you can use Composite, but I did not get how you came to pseudo code.

Composite pattern compose objects into tree structures to represent part-whole hierarchies. Group of objects is to be treated in the same way as a single instance of an object.

Component interface defines common method/methods for leafs and composites.

Leaf implements Component interface, but catch is that you can have multiple leaf objects(numeric, text, ...).

Composite implements Component interface, but it is container for leaf objects as well.

So usage can be:

Component leaf1 = new Leaf(); //numeric entry
Component leaf2 = new Leaf(); // text entry

Composite composite = new Composite();
composite.add(leaf1);
composite.add(leaf2);

composite.operation(); // showData()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM