前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >防止在C#中滥用接口

防止在C#中滥用接口

作者头像
zls365
发布2021-04-23 12:44:15
1.4K0
发布2021-04-23 12:44:15
举报
文章被收录于专栏:CSharp编程大全

在设计应用程序时,通常需要使用接口和抽象类。本文讨论了一些常见的“接口滥用”的例子以及我们可以用来避免它们的策略。它还讨论了“编程到接口而不是实现”这一信条的含义

什么是接口?首先,让我们了解一下接口以及为什么在编程中需要它们。接口严格来说是一个契约;它没有任何实现。接口只包含成员声明。可以有方法声明,但不能有定义。接口中声明的成员应该在扩展或实现接口的类型(类和结构)中实现。接口不能包含字段。接口不能序列化,因为它不能有数据成员。正如我所说,接口只能有声明,不能有定义。你知道吗

避免对接口进行更改扩展接口的类或结构应实现其所有成员。如果实现发生了变化,代码仍然可以工作。但是,如果契约(即接口)发生更改,则必须更改扩展接口的所有类型的实现。换句话说,对接口的任何更改都将影响扩展接口的所有类型。扩展接口的类型必须遵守约定。因此,只在很少需要更改接口时才使用接口。另外,创建一个新的接口通常比更改一个现有的接口要好

程序到接口,而不是实现您可能偶尔会听到“编程到接口而不是实现”这样的话。您可能已经在代码中使用了接口,但仍然在对实现进行编程。现在让我们来检查这两种方法之间的区别

当您对一个接口进行编程时,您使用的是最通用的抽象(接口或抽象类),而不是具体的实现。由于接口保证了一致性,因此对接口编程意味着您可以以一致的方式处理相似的对象。在这样做的过程中,您与实现是分离的,也就是说,您的实现可以不同。这也为您的设计增加了灵活性

下面的代码片段演示了对接口的编程。考虑一个名为IRepository的接口,它包含几个方法的声明。ProductRepository和CustomerRepository类扩展了IRepository接口并实现了在IRepository接口中声明的方法,如下所示

代码语言:javascript
复制
public interface IRepository
    {
        //Some code
    }
    public class ProductRepository: IRepository
    {
        //Some code
    }
    public class CustomerRepository: IRepository
    {
        //Some code
    }

以下代码可用于创建ProductRepository的实例

代码语言:javascript
复制
IRepository repository = new ProductRepository();

其思想是您可以在这里使用任何实现IRepository接口的类。所以,下面的语句也是有效的

代码语言:javascript
复制
IRepository repository = new CustomerRepository();

当您对一个实现编程时,这种一致性就丢失了。相反,您通常会有一些构造,例如“if..else”或“switch..case”语句,用于控制代码中的行为

避免过度使用接口将每个类与一个接口相关联不是一个好的做法。以这种方式过度使用接口会产生不必要的复杂性,引入代码冗余,违反YAGNI,并降低代码库的可读性和可维护性。接口用于将具有相同行为的对象组合在一起。如果对象没有相同的行为,则不需要进行此分组。当您不打算有多个接口实现时使用接口就是接口过度使用的一个例子

为与类的公共成员匹配的类创建接口非常常见。这样做根本不需要添加任何值—只需复制类的接口,而不添加任何真正的抽象

现在我们来看一个如何过度使用接口的示例。考虑以下名为IProduct的接口

代码语言:javascript
复制
public interface IProduct
    {
        int Id { get; set; }
        string ProductName { get; set; }
        double Price { get; set; }
        int Quantity { get; set; }
    }

Product类扩展了IProduct接口,如下所示

代码语言:javascript
复制
public class Product : IProduct
    {
        public int Id { get; set; }
        public string ProductName { get; set; }
        public double Price { get; set; }
        public int Quantity { get; set; }
    }

显然,我们不需要IProduct接口,因为接口及其实现是相同的。多余的代码是不必要的

让我们看另一个例子。下面的代码片段显示了一个名为IProductManager的接口,它声明了两个方法,即Save和Update

代码语言:javascript
复制
 public interface IProductManager
    {
        void Save(IProduct product);
        void Update(IProduct product);
    }

IProductManager接口包含ProductManager类的公共方法的声明。下面是ProductManager类的外观

代码语言:javascript
复制
 public class ProductManager : IProductManager
    {
        public void Save(IProduct product)
        {
           //Write your implementation here
        }
        public void Update(IProduct product)
        {
            //Write your implementation here
        }
    }

IProduct和IProductManager接口就是过度使用接口的例子。这两个接口都有一个实现,它们根本没有任何附加值

通过使用接口,您可以消除代码中不必要的耦合,并使代码易于测试。但是,应该避免过度使用接口。仅当接口有多个实现时才使用接口。当您有一个类要扮演许多角色或有多个职责时,也可以使用接口。在这种情况下,类可以实现多个接口—每个角色一个接口

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CSharp编程大全 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档