开发者

How can I make a family of singletons?

开发者 https://www.devze.com 2022-12-28 18:54 出处:网络
I want to create a set of classes that share a lot of common behavior. Of course in OOP when you think that you automatically think \"abstract class with subclasses\". But among the things I want thes

I want to create a set of classes that share a lot of common behavior. Of course in OOP when you think that you automatically think "abstract class with subclasses". But among the things I want these classes to do is to each have a static list of instances of the class. The list should function as sort of a singleton within the class. I mean each of the sub-classes has a singleton, not that they share one. "Singleton" to that subclass, not a true singleton. But if it's a static, how can I inherit it?

Of course code like this won't work:

public abstract A
{
  static List<A> myList;
  public static List getList()
  {
    if (myList==null)
      myList=new ArrayList<A>(10);
    return myList;
  }
  public static A getSomethingFromList()
  {
    List listInstance=getList();
    ... do stuff with list ...
  }
  public int getSomethingFromA()
  {
    ... regular code acting against current instance ...
  }
}
public class A1 extends A
{
  ...
}
public class A2 extends A
{
   ...
}

A1 somethingfromA1List=(A1) A1.getSomethingFromList();
A2 somethingfromA2List=(A2) A2.getSomethingFromList();

The contents of the list for each subclass would be different, but all the code to work on the lists would be the same.

The problem with the above code is that I'd only have one list for all the subclasses, and I want one for each. Yes, I could replicate the code to declare the static list in each of the subclasses, but then I'd also have to replicate all the code that adds to the lists and searches the list, etc, which rather defeats the purpose of subclas开发者_运维百科sing.

Any ideas on how to do this without replicating code?

Update

To clarify for BlueRaja and perhaps others, let me be a little more specific about what I'm trying to do.

I have a number of statuses and codes that require similar behavior. They are like enums in that I want type-safe instances for each possible code state, but they come in multiple sets so I cannot just make one enum for them all.

So for example I have order status, that has values for on-order, shipped, received, and some special values. I have item type, with values for merchandise versus service. I have stock versus custom. Etc.

If that was all there was to it I'd just make an enum for each. But there's other behavior I need, like ability to look up an object by a text value, e.g. when we read it from the database; building a drop down listing all the choices by a text description; etc. To the best of my knowledge, I can't do this with an enum because I have several sets of codes each with common behavior that I want to inherit, and I can't subclass an enum. Putting all the codes in a single enum would abandon type safety on one code versus another, as well as proving no ready way to collect the list of values for a particular code type.


You can use a static Map<Class, YourClass> = new ConcurrentHashMap<..>() in the parent class and use that map to add/retrieve the instances.

Though such large reliance on singletons sounds to me like a bad design - you should try to avoid it.


What is so bad about singletons?

Edit: After a question response: You say "I want to create a set of classes that share a lot of common behaviour" - that, to me, does not suggest "abstract class with subclasses at all", as an abstract class has no behaviour. It suggests a separate object implementing the common behaviour, and a lot of classes aggregating that separate object.


From the sounds of it, what you really want is an enum class with custom properties and behaviours. See here for an example of the extreme power of enums in Java.


I would be thinking of a factory method:

public class Factory {
  private static final A1 a1Instance = new A1(
          Collections.synchronizedList(new ArrayList<something>(100)));
  private static final A2 a2Instance = new A2(
          Collections.synchronizedList(new ArrayList<something>(100)));

  public static A getA1() { return a1Instance; }
  public static A getA2() { return a2Instance; }
}

Your A wouldn't need all those static methods anymore of course.


You can use the indexes of class, the static list don't need yow can just use the indexes that refer of the instace of these class of cors and the subclass. Here is a excample : http://www.java2s.com/Code/CSharp/Class-Interface/Indexerallowarraylikeindex.htm


If you need a singleton functionality and at the same time want to get benefit of inheritance you should consider Dependency Injection frameworks such as Spring or PicoContainer. Even if your application is quite small your life still will be easier with a framework managing dependencies.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号