必会重构技巧(三):提取接口
提取接口:当有多余一个类使用另外一个类中的方法时,可以考虑引入接口,解除这种依赖。
举例理解:比如说类A中有个方法为Call(Type T),类B和类C中都有方法都要调用Call这个方法,那么我们推荐引入一个接口,这样传参时可以直接new一个接口,可以解除调用方法和实现方法之间的耦合关系。面向接口编程也算是OO中比较重要的吧。
项目实例:一般而言在设计的时候,对于比较可能扩展的部分都会用接口或者是抽象方法来处理,对于接口,个人并不是很喜欢,因为接口写好了要修改就很困难,只能再加新的接口,这对设计的要求很高,抽象方法相对好用点。下面的代码扩展于原文的Demo Code,希望可以讲得稍微详细点。
先来看看原始的未经过重构的代码:
实现类
public class ClassRegistration
{
public void CreateAdmin()
{
// create registration code
}
public void CreateUser()
{
// create registration code
}
public decimal Total { get; private set; }
}
public class RegistrationProcessor
{
public decimal ProcessRegistrationAdmin(ClassRegistration registration)
{
registration.CreateAdmin();
return registration.Total;
}
public decimal ProcessRegistrationUser(ClassRegistration registration)
{
registration.CreateUser();
return registration.Total;
}
}
调用方法
protected void CreateAdmin_Click(object sender, EventArgs e)
{
RegistrationProcessor registrationProcessor = new RegistrationProcessor();
registrationProcessor.ProcessRegistrationAdmin(new ClassRegistration());
}
protected void CreateUser_Click(object sender, EventArgs e)
{
RegistrationProcessor registrationProcessor = new RegistrationProcessor();
registrationProcessor.ProcessRegistrationUser(new ClassRegistration());
}
上面的伪代码实现了创建Admin和User的主要类和主要实现方法及调用事件,这样的代码看似没问题,其实是非常不方便扩展的。请大家想想,如果我现在要添加一个创建Viewer用户的事件,需要改几个方法?我整理如下:
(1)在类ClassRegistration中增加一个CreateViewer()的方法;
(2)在类RegistrationProcessor中增加一个处理注册Viewer用户的方法ProcessRegistrationViewer();
(3)在CreateViewer的Button事件中添加代码;
如上,改的地方实在太多了,这里对于创建用户的这个方法完全可以抽象出来,把它作为一个接口方法处理,重构后的代码如下:
重构后的实现类
public interface IClassRegistration
{
void Create();
decimal Total { get; }
}
public class ClassRegistrationAdmin : IClassRegistration
{
public void Create()
{
// create registration code
}
public decimal Total { get; private set; }
}
public class ClassRegistrationUser : IClassRegistration
{
public void Create()
{
// create registration code
}
public decimal Total { get; private set; }
}
public class RegistrationProcessor
{
public decimal ProcessRegistration(IClassRegistration registration)
{
registration.Create();
return registration.Total;
}
}
重构后的调用方法
protected void Create_Click(object sender, EventArgs e)
{
var btn = sender as Button;
if (btn != null)
{
RegistrationProcessor registrationProcessor = new RegistrationProcessor();
IClassRegistration registration;
switch (btn.CommandArgument)
{
case "CreateAdmin":
registration = new ClassRegistrationAdmin();
registrationProcessor.ProcessRegistration(registration);
break;
case "CreateUser":
registration = new ClassRegistrationUser();
registrationProcessor.ProcessRegistration(registration);
break;
}
}
}
如上,提取接口后,对于新类型用户的创建就方便多了,新建一个基于接口的创建新用户的类,然后在Button的事件中加个分支就好了。并且我们只需要实现接口中的方法Create()就OK了。
面向接口编程,能大大提高程序的可扩展性和可维护性,对于程序的模块化很有帮助,非常适合用于多模块,多团队合作的项目。