如何在子类中实现单例模式

本文关键字:实现 单例模式 子类 | 更新日期: 2023-09-27 18:12:51

我在visual studio 2010中练习。net。我正在申请银行账户的子类型和AccountState的子类型,即:Bronze State, Gold State, Silver State, Platinum State。每种帐户类型的上限和下限不同。

Public class AccountState
{
    public double upperlimit {get;set}
    public double lowerlimit {get;set} 
}
public class BronzeState : AccountState
{
    private static BronzeState bronzeState;
    private BronzeState(){}
    public GetInstance()
    {
        if (bronzeState != null)
            return bronzeState;
        else
        {
            bronzeState = new BronzeState();
            return bronzeState; 
        }
    }
}
//Same goes for GoldState, SilverState, PlatinumState

如何为所有帐户状态设置自动实现属性的上限和下限,并保持单例?

如何在子类中实现单例模式

您的单例实现是正确的。现在你有了这个,剩下的就很像常规的继承了。请记住,您可以使用"this"操作符引用继承的方法、属性和字段。

紧跟您现有的代码,要设置从子类继承的属性的值,您需要,例如:

this.upperlimit = 5000;

那么问题就是你应该在子类的什么地方设置限制。构造函数可能是确保在使用之前确保设置上限的地方。这看起来像:

private BronzeState()
{
    this.upperlimit = 5000;
}

我要注意的一件事,虽然它没有直接回答这个问题,是你应该考虑你希望谁能够改变AccountState的限制。现在,任何其他类都可以看到您的限制并设置。似乎你只希望它们能被子类改变。

要做到这一点,你需要使用protected setter,如下所示:

public double upperlimit { get; protected set; }

这确保了该值可以被任何人看到,但只能由父类或子类设置。

完整的画面将是:

public class AccountState
{
    public double UpperLimit { get; protected set; }
    public double LowerLimit { get; protected set; }
}
public class BronzeState : AccountState
{
    private BronzeState()
    {
        this.UpperLimit = 5000;
        this.LowerLimit = 1000;
    }
    public static BronzeState GetInstance()
    {
        ...
    }
}

在不太了解您的场景细节的情况下,我还会考虑在此场景中使用抽象属性。例如:

public abstract class AccountState
{
    public abstract double UpperLimit { get; }
    public abstract double LowerLimit { get; }
}
public class BronzeState : AccountState
{
    public override double UpperLimit
    {
        get { return 5000; }
    }
    public override double LowerLimit
    {
        get { return 1000; }
    }
    public static BronzeState GetInstance()
    {
        ...
    }
}

这种设计的优点是强迫子类定义上限和下限,并鼓励它们不要改变,如果这是如此可取的话。选择哪种设计更好取决于它适合的更广泛的场景。


在上面的任何一个例子中,要在类之外访问中的值,如下:
double limit = BronzeState.GetInstance().UpperLimit;

你可以在MSDN上阅读更多关于c#中的继承(包括我上面提到的东西)。

你的代码被切断了,所以我假设你的GetInstance方法是这样的…

public static BronzeState GetInstance()
{
     if (bronzeState != null)
          return bronzeState;
     else
     {
          bronzeState = new BronzeState();
          return bronzeState; 
     }
}

要使用这个,你应该能够简单地这样做。

BronzeState.GetInstance().upperlimit = //...The value for the upperlimit.

注释不允许我插入代码,所以我添加了另一个答案。这只是为了展示如何创建Singleton对象。其他人可能有更好或不同的方法,但这是有效的。要正确管理单例,必须只有该类的一个实例。您可以将类设置为静态,但在某些情况下这是不行的。为了防止另一个类实例化它,你必须只使用"私有"构造函数。您还必须在单例对象中创建并保存自己作为字段的静态引用,最后公开返回该字段的静态方法。如果你想要超级兴奋,你可以引入更多的逻辑来防止反射复制这个对象,但我觉得这有点过头了。

    <
  1. 私有构造函数/gh>
  2. 私有静态实例
  3. 公共静态方法返回实例
public class MySingleton
{
    private static MySingleton instance = new MySingleton();
    private MySingleton() { }
    public static MySingleton Instance => instance;
}

出于某种原因,它不让我把例子放在代码块中…一直给我一个错误,所以我把它放在引号

此时,您可以在对象中放入所需的任何数据和属性,并根据需要在构造函数中初始化它们。将它们公开为普通的类属性,而不是静态的,其他类所要做的就是

MySingleton.Instance.SomeProperty

在。net中,你不像在其他框架或语言中那样经常使用单例。你所拥有的是有限的,而不是单一的。你有三种类型的账户状态。如果你忠于。net实践,你可以这样实现它:

public class AccountState
{
    private AccountState(double upper, double lower)
    {
       this.UpperLimit = upper;
       this.LowerLimit = lower;
    }
    public double UpperLimit { get; }
    public double LowerLimit { get; }
    public static AccountState Bronze { get; } = new AccountState(10, 0);
    public static AccountState Silver { get; } = new AccountState(20, 11);
    public static AccountState Gold { get; } = new AccountState(25, 21);
}

你可以这样使用它:

Console.WriteLine(AccountState.Bronze.UpperLimit);