如何设计两个相似(但不完全)的类?

时间:2013-08-01 09:09:01

标签: c# .net architecture solid-principles

情况如下。 我们有两台来自不同供应商(制造商)的打印机。 我们希望顶级代码不会意识到有关提供程序的详细信息,只需使用统一的API。 所以我开始提取界面。

public interface IPrinterProvider {
    bool Connect(string comPort);
    bool IsConnected();
}

行。 现在,我意识到一台打印机需要Password属性,但另一台则不需要。 那么,我该怎么办?

再一次。 据我所知,我将有一个或几个接口和几个实现者。 但是呼叫者将如何工作? 我应该创建一个单独的类,它可能不实现任何接口?例如:

public class CommonPrinterProvider {
    private IPrinterProvider printerProvider;
    public CommonPrinterProvider(IPrinterProvider printerProvider) {
        this.printerProvider= printerProvider;
    }
}

所以,总共有两个问题。

5 个答案:

答案 0 :(得分:5)

我会将打印机“设置”(或者更确切地说,“连接设置”)封装到另一个类中,并将其包含在interface中。有点像这样:

public class PrinterSettings {
    public string Password { get; set; }
    public int Port { get; set; }
    /* .. others .. */
}

public interface IPrinterProvider {
    void Initialize(PrinterSettings settings);
    bool Connect(string comPort);
    bool IsConnected();
}

然后,每个实现都可以以他们认为合适的方式处理设置。

答案 1 :(得分:1)

最好尽可能统一界面。确实的接口实现(类)会有差异,但处理它们应隐藏在strategies中。 调用者应该使用接口,最好将实例化放到IoC层。下一步是创建将为特定实现带来所有必需设置的服务。每个服务类型将由每个单独的提供者使用。然后你会有一个很好的SOC。在这个级别,你将拥有相同界面的并行结构,并实现Abstract Factory它是一个完美的契合。

答案 2 :(得分:1)

一种方法是提供IPrinterProvider的继承接口。这个新界面将具有密码添加将添加的所有属性等:

public interface IPrinterProvider
{
    bool Connect(string comPort);
    bool IsConnected();
}

public interface IPasswordPrinterProvider : IPrinterProvider
{
    string Password { get; set; }
}

这种方式继承的接口包含IPrinterProvider所有相同的东西,但也可以自己扩展。没有密码选项的那些实现原始IPrinterProvider的类将没有负担。

答案 3 :(得分:0)

您可以按原样保留您的界面,并实现一个接收密码的类,而另一个不接受密码:

public class PasswordPrinterProvider : IPrinterProvider
{
     private readonly string password;
     public PasswordPrinterProvider(string password)
     {
         this.password = password;
     }
     public bool Connect(string comPort) {...}
     public bool IsConnected() {...}
}

答案 4 :(得分:-1)

你可以使用这样的东西...... 有点类似于工厂模式。

抽象类:

public abstract class PrinterProvider
{
    public string Password{get;private set;}
    public abstract bool connect(string port);
    public bool IsConnected()
    {
        return true;
    }
}

ConcreteClass 1:

public class PrinterCompany1 : PrinterProvider
{
    public override bool connect(string port)
    {
        // some code here
        // If it needs password
        return true;
    }
}

ConcreteClass 2:

public class PrinterCompany2:PrinterProvider
{
    // Printer that doesnt need password
    public override bool connect(string port)
    {
        return false;
    }
}

最后在动态多态性的帮助下访问所有这些具体类......

        PrinterProvider provider;

        // First provider
        provider = new PrinterCompany1();
        provider.connect("temp");
        // Second provider
        provider = new PrinterCompany2();
        provider.connect("temp2");

请参阅工厂模式以获取更详细的说明......