简体   繁体   中英

How to implement singleton pattern in subclass

I am practicing .net in visual studio 2010. I am making an application for bank accounts with sub types and AccountState with subtype ie: Bronze State , Gold State , Silver State , Platinum State . Each account type is different by upper limit and lower limit.

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

How can I set AutoImplemented properties upperlimit and lower limit for all Account State and keeping Singleton in mind?

Your code was cut so I'm assuming your GetInstance method is like this...

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

To use this you should be able to simply do this.

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

Post what you've tried that isn't working.

You have the singleton implementation correct. Now that you have that, the rest is very much like regular inheritance. Remember that you can reference inherited methods, properties and fields using the "this" operator.

Following closely with your existing code, to set the values of the inherited properties from the sub-class, you need to, for example:

this.upperlimit = 5000;

The question then is where you should set the limit in the sub-class. The constructor would be a likely place to ensure that the upper limit is guaranteed to be set before use. This would look like:

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

One thing I will note, although it isn't directly answering the question, is you should consider who you want to be able to change the limits of an AccountState. Right now, your limits can be seen and set by any other class. It seems like you would only want them changeable by the sub-classes.

To do this, you will want to use a protected setter, like so:

public double upperlimit { get; protected set; }

That ensures that the value can be seen by anyone, but can only be set by the parent class or sub-classes.

The full picture would then be:

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()
    {
        ...
    }
}

Without knowing too much about the specifics of your scenario, I would also consider using abstract properties in this scenario. For example:

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()
    {
        ...
    }
}

This design has the advantage of forcing the sub-class to define the upper and lower limits, as well as encourages them not to change, if that is so desirable. Choosing which design is better would depend on the broader scenario this is fitting into.


In either of the examples above, to access the values from outside the class would look like:

double limit = BronzeState.GetInstance().UpperLimit;

You can read more about inheritance in C# (including the things I mentioned above) on MSDN .

The comment wouldn't allow me to insert code so I'm adding another answer. This is just to show how I create a Singleton object. Others may have a better or different way but this is effective. To manage the singleton correctly you must have only a single instance of that class. You could make the class static but in some cases this won't do. In order to prevent another class from instantiating it you must only use 'private' constructors. You must also create and hold a static reference of yourself as a field in the singleton object and finally expose a static method that returns that field. If you want to get super carried away you could introduce more logic to prevent reflection from duplicating this object as well but that's over the top IMO.

  1. Private Constructor
  2. Private Static Instance
  3. Public Static Method returning Instance
 public class MySingleton { private static MySingleton instance = new MySingleton(); private MySingleton() { } public static MySingleton Instance => instance; } 

For some reason it wouldn't let me put the example in code blocks... Kept giving me an error so I just put it in Quote.

At this point you can put any data and properties you want in the object and initialize them in the constructor if you want. Expose them as normal class properties, not static, and all any other class will ever have to do is

MySingleton.Instance.SomeProperty

In .NET you don't use singletons as often as in other frameworks or languages. What you have is a finite amount, not a singleton. You have 3 types of account state. If you stay true to .NET practices, you could implement it this way:

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);
}

You could then use it like this:

Console.WriteLine(AccountState.Bronze.UpperLimit);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM