单身继承

时间:2010-01-30 01:28:08

标签: design-patterns singleton

如何从单例类继承到需要相同功能的其他类? 这样的事情会有意义吗?

4 个答案:

答案 0 :(得分:12)

Jon Skeet wrote about this一会儿回来。使用Singleton可以实现继承的好处一些,尽管使用嵌套的内部类确实有一些不足之处。它没有无限的可扩展性,它只是让Singleton在运行时选择自己的实现的技术。

实际上,继承Singleton并没有太大意义,因为Singleton模式的一部分是实例管理,一旦你已经拥有了一个基本类型的物理实例,那么覆盖其中的任何一个都为时已晚派生类型。即使你可以,我怀疑它可能会导致设计难以理解,甚至更难以测试/维护。

答案 1 :(得分:4)

您可以继承单例并使用模板(C ++)或泛型(C#.NET)进行“重用”或微调。

我在我的博客(www.devartplus.com)中发布了一系列关于此主题的帖子:

1)C#.NET中的Basic singleton inheritance

2)C#.NET中的线程安全单例继承

3)C ++中的几个单例实现

邀请您访问这些链接,并分享您的所有意见。 祝你好运。

答案 2 :(得分:0)

有人可以随意纠正我,但我理解它的方式,并且有一次错误:

public class BaseClass
{
  protected static List<string> ListOfSomething { get; set; }
}

public class ChildClass
{
  protected static List<int> ListOfSomethingElse { get; set; }
}

public class AnotherChildClass
{
  protected static List<int> ListOfSomethingElse { get; set; }
}

两个子类都会共享相同的 ListOfSomething,他们没有自己的副本。相同的静态将在所有孩子之间共享。这是单身行为和继承的蜕皮。丝毫说...你不应该这样做,你可能会遇到某些东西

如果你不是在谈论这样的事情......我不确定你说的是什么单身,并且一个例子会有很大帮助,因为单身人士有很多利基用途。

答案 3 :(得分:0)

有几种使用内部类和反射的解决方案(其他答案中提到了其中一些)。但是,我相信所有这些解决方案都涉及客户端与派生类之间的紧密耦合。

这是一种允许客户端仅依赖基类并且可以扩展的方法。

基类与通常的实现类似,不同之处在于我们将其定义为抽象类(如果实例化基类是合法的,则也可以像常规单例一样定义它)

public abstract class Animal {
    protected static Animal instance;
    public static Animal theInstance(){
        assert instance != null : "Cannot instantiate an abstract Animal";
        return instance;
    }
    abstract void speak();
}

任何子类型都有其自己的Instance方法(您不能覆盖静态方法)。例如:

public class Dog extends Animal{
    protected Dog(){}

    public static Animal theInstance(){
        if (instance == null){
            instance = new Dog();
        }
        return instance;
    }

    @Override
    void speak() {
        System.out.println("Wouf");
    }
}

在主类中,您将编写Dog.theInstance(),随后的任何客户端都将调用Animal.theInstance()。这样,客户端可以完全独立于派生类,并且您可以添加新的子类而无需重新编译客户端(开放式封闭原则)。