SwimBikeRun
SwimBikeRun

Reputation: 4460

What's another way to get the same functionality as implementing an interface in a static class?

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
}

Upvotes: 1

Views: 128

Answers (1)

Keith Payne
Keith Payne

Reputation: 3082

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
}

Upvotes: 4

Related Questions