1

我有两个类,服务器和客户端。服务器需要在多个线程中实例化客户端,客户端有一个需要提供自定义实现的虚拟成员。我的问题是。Client 类应该是 Server 类的嵌套类,还是我应该使用接口和依赖注入将自定义实现放入 Server 类。现在,Client 类也有许多私有方法,它们提供了一些不应更改的标准逻辑。

public class Server
{
    public void DoWork()
    {
        for (var i = 0;i < 10; i++)
        {
            Client client = new Client();
            client.Process(i);
        }
    }
}

public class Client
{
    private void doSomething() 
    { 
       ...
    }

    // Needs to be overridden and provide custom logic
    public virtual string Process(int i)
    {
        return i.ToString();
    }
}

工作示例:

public interface IClient
{
    string Process(string message);
}

public abstract class Client : IClient
{
    public virtual string Process(string message)
    {
        return message;
    }
}

public class CustomClient : Client
{
    public CustomClient() { }

    public override string Process(string message)
    {
        return string.Format("Custom Client:{0}", message);
    }
}

public class Server
{
    private Func<IClient> createClient;    

    public Server() { }

    public Server(Func<IClient> client)
    {
        createClient = client;
    }

    public void DoWork()
    {
        for (var i = 0; i < 10; i++)
        {
            IClient = client = createClient();
            client.Process(string.Format("Client #{0}", i));
        }
    }
}

测试程序...您将逐步查看它是否命中了 CustomClient

class Program
{
    static void Main(string[] args)
    {
        Func<CustomClient> factory = () => new CustomClient();
        var server = new Server(factory);
        server.DoWork();
    }
}
4

2 回答 2

1

是否应该注入或修复依赖项的问题有一个简单的答案 - 提供作为更改主题的逻辑的类是要注入的候选对象。另一方面,如果您不打算更改逻辑,您可以针对固定类型进行编码,就像使用大多数基类库一样。

您所描述的听起来像是 DI 的场景 - 如果您允许覆盖客户端类,那么您假设更改是可能的。DI 是同时处理依赖和变化的最明显的方法之一。

于 2013-04-06T17:00:52.800 回答
1

如果服务器需要创建客户端,我会将工厂方法传递给服务器以供其使用。所以我会去依赖注入。

例如:您可以将Servera 传递给构造函数Func<IClient>并将其分配给一个名为的私有字段,比如说,createClient然后代替

Client client = new Client();

采用

IClient client = createClient();

这样你就可以完全解耦服务器和客户端。

我更喜欢使用简单的Func委托而不是完整的工厂类,因为它 (a) 更易于使用并且 (b) 更松散耦合。

于 2013-04-06T18:07:27.460 回答