Bruno Tavares
Bruno Tavares

Reputation: 462

Design Pattern for Objects of the same type sharing various fields

The title may sound strange, but it's easier with the explanation:

Basically I have this class X. There is always a even number of those objects. For each two of those objects should exist 1 list that can be acessed from both of them.

For example if I create 4 X objects: A1, A2, B1, B2, I will need to have 2 lists, one that can only be acessed by A1 and A2 and another one only to be acessed by B1 and B2.

Thanks in advance

Upvotes: 0

Views: 440

Answers (4)

NickJ
NickJ

Reputation: 9559

Can you encapsulate the 2 objects and a list into another object? In this example, your objects are still instances of X, and the encapsulating class is Y:

/**
  * Encapsulates 2 X's and a List
  */
public class Y {

  private X x1;
  private X x2;
  private List list;

  public Y() {
    list = //..create list
    x1 = new X(list);
    x2 = new X(list);
  }
}

Have this class in the same package as X, and hide X's constructor to package level (default). If it's not the default (no arguments) constructor (as is the case here), write a private constructor.

Upvotes: 2

user3001
user3001

Reputation: 3487

Let me improve the answer of Tim B. I also think that a factory pattern is what you need. First, class X takes a reference to a list.

abstract class X<T> { 
  List<T> list;

  public X(List<T> l) { list = l; }
}

By contract, all classes extending X have to take a list and hand it over to super(list) in the constructor, for example

abstract class A<T> extends X<T> { 

  public A(List<T> l) { super(L); }
}
// others like B also declared similar

In the factory, we "count" the instances in a Map<Class, List<?>> and hand the associated list over to the implementation.

public class Factory {

    Map<Class<?>, List<?>> class2List = new HashMap<Class<?>, List<?>(); // you may need a synchronized version here

    <T> X<T> createInstance(Class<X<T>> class) {
        List<T> list;
        // Idea: If the HashMap contains the class, we already created one instance before.
        if (class2List.contains(class)) {
            // second instance. Remove to implicitly count from 0 again
            list = (List<T>) class2List.remove(class);
        } else {
            list = new ArrayList<T>();
            class2List.add(list);
        }
        // now create the instance depending on the class and give it the list.
        // For example
        X<T> result;
        if (class.equals(A.class)) {
            result = new A<T>(list);
        } else  {
            result = new B<T>(list);
        }
        return result

    }


}

Upvotes: 1

BobTheBuilder
BobTheBuilder

Reputation: 19284

You can create one list for each two instances, than create each of the two using a giving the list as constructor argument.

Each object will access its list only, so B1,B2 will use a different list than A1,A2.

You can create a Map<String, List<>> that holds name and list.

Each time you create an object, get its list from the map. If it doesn't in map, create a new list and put it there.

Upvotes: 0

Tim B
Tim B

Reputation: 41168

You probably want a factory here. One call to the factory generates A and B, sets up the shared members, then returns them to you either in an Array or in some sort of results Object.

Upvotes: 0

Related Questions