1

I have made some functions to control hardware. However in the event real hardware is present (G.demomode = true), I would like to also call the real hardware's functions, which implements the same interface.

You can see my attempt below, but the line DVDDHW.setSupply(voltage); isn't quite right, namely because a static class can't implement an interface. Is there a better way to do this?

The end goal is to define an interface (maybe this isn't the right word) to follow for the HW engineer so he can specify the unspecified functions in the interface.

I tried to do my due diligence of searching, and I found several threads on this topic. However, I couldn't wrap my head around how to implement their alternative solutions for my use case. Any help or pointers would be great.

Thanks!

public interface IPowerSupply
{
    bool setSupply(double voltage);
}

public static class DVDDHW : IPowerSupply
{
    public bool setSupply(double voltage)
    {
        i2c.write("DVDD ON"); //or something that involves turning the real hardware on
        return true;
    }
}

public class DVDD : IPowerSupply
{
    public bool setSupply(double voltage)
    {
        DevLog.DevLog.addToLog(string.Format("Supply set: {0}V: ", voltage) + this.GetType().ToString());
        if (G.demoMode == false) //demoMode is false because HW is connected
            {
                DVDDHW.setSupply(voltage); //What is another way to accomplish this?
            }
        return true;
    }
}


//Code to execute below:
foreach PowerSupply ps in PowerSupplyList // List contains an instance of DVDD in this example
{
    ps.setSupply(3.5); // Set each supply to 3.5V
}
1
  • 2
    why is your class static? Commented Feb 5, 2015 at 2:19

1 Answer 1

4

A singleton is the way to go if you only want one instance of a class that implements an interface.

The MS how-to is https://msdn.microsoft.com/en-us/library/ff650316.aspx.

For your code, the following will work:

public interface IPowerSupply
{
    bool setSupply(double voltage);
}

public class DVDDHW : IPowerSupply
{
    IPowerSupply _instance;

    public static IPowerSupply Instance
    {
        get
            {
                if (_instance == null)
                    _instance = new DVDDHW();
                return _instance;
            }
    }
    private DVDDHW() { }

    public bool setSupply(double voltage)
    {
        i2c.write("DVDD ON"); //or something that involves turning the real hardware on
        return true;
    }
}

public class DVDD : IPowerSupply
{
    public bool setSupply(double voltage)
    {
        DevLog.DevLog.addToLog(string.Format("Supply set: {0}V: ", voltage) + this.GetType().ToString());
        if (G.demoMode == false) //demoMode is false because HW is connected
            {
                DVDDHW.setSupply(voltage); //What is another way to accomplish this?
            }
        return true;
    }
}


//Code to execute below:
foreach PowerSupply ps in PowerSupplyList // List contains an instance of DVDD in this example
{
    ps.setSupply(3.5); // Set each supply to 3.5V
}

There are some slight differences in the way that the singleton behaves when compared to a static class. These are important if your application is multi-threaded, or if there is some other code in the constructor that you expect to run when the type is first accessed. If these things don't mean anything to you then you don't have to worry about it :)

EDIT:

As Scott pointed out, the code in the get accessor is unnecessary. A simplified version is this:

public class DVDDHW : IPowerSupply
{
    static readonly IPowerSupply _instance = DVDDHW();

    public static IPowerSupply Instance
    {
        get { return _instance; }
    }

    private DVDDHW() { }

    public bool setSupply(double voltage)
    {
        i2c.write("DVDD ON"); //or something that involves turning the real hardware on
        return true;
    }
}

Also, this code had a typo (fixed):

//Code to execute below:
foreach IPowerSupply ps in PowerSupplyList // List contains an instance of DVDD in this example
{
    ps.setSupply(3.5); // Set each supply to 3.5V
}
Sign up to request clarification or add additional context in comments.

4 Comments

There is no reason to lazy load DVDDHW, just use a simple getter and static readonly IPowerSupply _instance = DVDDHW(); to instantiate it you greatly reduce your risk of somthing actually going wrong and getting more than one copy of your singleton. If "those things really do don't mean anything to you" just skip the fancy lazy loading and do a basic static initializer.
Agreed. The MS link shows the lazy loading, however I'll add this to the answer.
Yes, but if you read the fine print it mentions that the pattern is not thread safe and a rule of thumb is all static members should be thread safe. If you keep reading on the page the Static Initialization example is exactly what the new update does.
I ended up just using a class and not worrying about making it static or not

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.