C#中的单例模式

时间:2013-09-26 07:15:11

标签: c# java oop design-patterns

Singleton模式的伟大之处在于:仅初始化对象(实例)一次。 然后我们可以与非静态成员进行交互。 但是关于Singleton模式的更强大的是构造函数。

如果我们不需要初始化对象的构造函数,那么单例模式就没有意义了,我们可以使用静态类。

但是如果我们确实需要将参数放入构造函数中呢?

构造函数有一个角色,有两个选项:一个用于将对象初始化为初始值,第二个是将对象初始化为通过参数获取的值,那么我们可以说单例模式省略了第二个吗?

否则,单例模式和静态类之间的差异是什么?

谢谢, 雅各布

3 个答案:

答案 0 :(得分:1)

“Singleton模式是:只对对象(实例)初始化一次”,所以你可以这样做:

public class MyClass   {

    MyClass me  = null;

    //private CTOR 
    private MyClass  () {
    }

    public static MyClass  ConstructMe(..parameters..) {

         if(me != null) 
            return me;

         me = new MyClass();
         ....setup parameters .... 
         return me,
    }

}

您传递参数,并且您只能有一个实例。

如果这不是您所要求的,请澄清。

答案 1 :(得分:1)

1)没有什么能阻止你在单例模式中实现一个带有参数的初始化器,只要它总是需要那些参数。伪代码:

class single{
    private static single instance;
    private single(){
        default args;
    }
    private single(arg1, arg2){

    }
    public static init(){
        if(instance == null){
           instance = new single();
        }
        return instance;
    }
    public static init(arg1, arg2){
        if(instance == null){
           instance = new single(arg1, arg2);
        }
        else{
           instance.setArg1(arg1);
           instance.setArg2(arg2);
        }
        return instance;
    }
}

2) 单例类可以扩展,并且可以扩展其他类 - 提供OOP的全部功能,静态类只是组织函数的结构化方法。

答案 2 :(得分:0)

如果你需要在你的单例构造函数中使用参数,那么你就有一个设计缺陷IMO。

您可以使用setter在实例化后初始化您的成员,也可以将所需的实例作为成员函数的参数传递。

public class MyClass {

    static MyClass single = null;
    MyMember member;

    private MyClass() {

    }

    public static MyClass getInstance() {
        if(single == null)
            single = new MyClass();
        return single;

    }

    //------------------------------------------------------------
    // First approach using setter
    public void setMember(MyMember member) {
        this.member = member;
    }

    public void doSomething() {
        member.foo();
        // do something
    }

    //------------------------------------------------------------
    // Second approach pass by parameter
    public void doSomething(MyMember param) {
        param.foo();
        // do something
    }
}