使用接口 - 设计模式方面

Nao*_*aor 4 .net c# design-patterns interface

我正在寻找一篇好的和简短的文章+如何使用接口的例子.我对技术部分并不感兴趣,但我需要设计部分.例如,如何使用接口进行编程,何时以及如何创建实现,设计用于使用接口进行常规开发的模式.

我有很多类似的类,它们以多种方式重复自己.我想使用接口和抽象类来使事情更加模块化 - 但我无法找到如何正确地做到这一点.

mfa*_*nto 13

接口定义合同.这是一个对象将以某种方式表现的承诺.在学习接口之前,您倾向于用具体的术语来考虑对象.例如,假设我们有一个产品列表:

List<string> products = new List<string>() { "desktop", "laptop", "server" };
Run Code Online (Sandbox Code Playgroud)

我们有一种方法可以打印出我们的产品:

void PrintProducts(List<string> products)
{
     foreach (string product in products)
     { 
          Console.WriteLine(product);
     }
}
Run Code Online (Sandbox Code Playgroud)

我们的方法与List的具体类型相关联.它需要吗?C#中有很多不同类型的集合:Lists,Arrays,ReadOnlyCollection等.你真正需要做的就是遍历它们.列表有很多方法,数组没有,但你没有在这里使用任何方法.幸运的是,它们都实现了IEnumerable接口.这意味着它们都是"契约约束"以便能够被列举.

改变方法如下:

void PrintProducts(IEnumerable<string> products)
{
     foreach (string product in products)
     { 
          Console.WriteLine(product);
     }
}
Run Code Online (Sandbox Code Playgroud)

意味着您现在可以传入数组,列表或您自己创建的某个唯一容器.

另一个例子:假设您有一个数据存储库:

public class DatabaseRepository
{
    public void AddProduct(Product product)
    {
        // connect to the database
        // add the product
    }
}
Run Code Online (Sandbox Code Playgroud)

你有一些需要这个数据库的类:

public class ProductManager
{
    DatabaseRepository _repository;

    public ProductManager(DatabaseRepository repository)
    {
         _repository= repository;
    }
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,这个类与您的数据库绑定在一起.如果您决定更改为存储为XML文件或存储在某个云键值存储中,该怎么办?您将不得不更改您的ProductManager,这很困难且容易出错.假设我们定义了一个接口:

public interface IRepository {
    void AddProduct(Product product);
}
Run Code Online (Sandbox Code Playgroud)

更改我们的ProductManager类以使用此接口:

public class ProductManager
{
    IRepository _repository;

    public ProductManager(IRepository repository)
    {
         _repository= repository;
    }
}
Run Code Online (Sandbox Code Playgroud)

意味着无论它是什么类型的存储库,我们都知道总会有一个方法AddProduct(Product product).我们现在可以创建我们的XML存储库:

public class XMLRepository : IRepository 
{
    public void AddProduct(Product product)
    {
         // write to an XML file
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我们可以自由地传入任一存储库:

ProductManager manager = new ProductManager(new DatabaseRepository())
Run Code Online (Sandbox Code Playgroud)

要么

ProductManager manager = new ProductManager(new XMLRepository())
Run Code Online (Sandbox Code Playgroud)

我们的ProductManager表现完全相同.它完全没有意识到具体类型是什么.

当您进入单元测试时,这变得非常有用.当您深入了解界面的工作原理时,您需要阅读控制反转.