开放封闭原则是面向对象的七大原则的核心
对功能扩展开放,修改的时候代码封闭
需求改变的时候,我们希望在不改变实体源代码(类、接口、方法)前提下,通过扩展功能,来满足我们新的需求
这里我们会产生一个误区,既然我的需求都改变了,那必然会去修改我们的代码,其实我们不应该死钻牛角尖,我们的面向修改代码封闭指的是:当我们的需求发生改变的时候,我们希望改动的是一个点的代码,不是改动大量的代码。不要牵一发而动全身。这就是高耦合 ,耦合性太强,我们应该去靠近低耦合。
举例说明:
使用代码。描述不同需求的用户去银行办理不同的业务。
- 先分析:禁忌在边写代码的时候边分析
1.会出现几个对象
2.每个对象的行为和属性
针对我们的这个例子。我们可以得出
对象1:用户
属性:记录不同的用户(存钱、取钱、转账)
对象2:柜员,帮助我们用户处理不同的业务
对象3:银行业务系统。处理存钱、取钱、转账
我们应该此刻能想到,我们的柜员只是用这个业务系统来干我们用户需要做的事情,实际上是业务系统在做,这里的柜员只是调用。
static void Main(string[] args)
{
银行客户 客户 = new 银行客户();
客户.客户类型 = "开户";
银行柜员 柜员 = new 银行柜员();
柜员.处理用户需求(客户);
Console.ReadKey();
}
public class 银行客户
{
public string 客户类型 { get; set; }
}
public class 银行柜员
{
private 银行业务系统 业务系统 = new 银行业务系统();
//需要调用我们的业务系统去处理用户的需求,因此这里我们应该写一个方法
public void 处理用户需求(银行客户 客户)
{
//调用银行业务系统,处理用户请求
switch (客户.客户类型)
{
case "存钱":
业务系统.存钱();
break;
case "取钱":
业务系统.取钱();
break;
case "转账":
业务系统.转账();
break;
default:
Console.WriteLine("目前没有办法处理您的业务!");
break;
}
}
}
public class 银行业务系统
{
public void 存钱()
{
Console.WriteLine("我是存钱业务!");
}
public void 取钱()
{
Console.WriteLine("我是取钱业务!");
}
public void 转账()
{
Console.WriteLine("我是转账业务!");
}
}
由此根据我们的需求我们就可以写出这样的代码。可是我们学过单一职责原则,因此我们设计的银行业务系统这个类是不满足我们单一职责原则的。以及我们的柜员处理业务类,也是设计非常差的。我们回过头看看这段代码其实仅仅符合开放原则(对功能扩展开放),但是不符合我们的封闭原则。
修改如下:
static void Main(string[] args)
{
I客户 客户 = new 客户存款接口类();
银行柜员 柜员 = new 银行柜员();
柜员.处理用户需求(客户);
Console.ReadKey();
}
public class 银行客户
{
public string 客户类型 { get; set; }
}
public class 银行柜员
{
private I银行业务系统 业务系统 ;
//需要调用我们的业务系统去处理用户的需求,因此这里我们应该写一个方法
public void 处理用户需求(I客户 客户)
{
//调用银行业务系统,处理用户请求
业务系统= 客户.银行业务系统();
业务系统.银行业务系统();
}
}
public interface I客户
{
I银行业务系统 银行业务系统();
}
public class 客户存款接口类 : I客户
{
public I银行业务系统 银行业务系统()
{
return new 存款接口类();
}
}
public class 客户取款接口类 : I客户
{
public I银行业务系统 银行业务系统()
{
return new 取款接口类();
}
}
public class 客户转账接口类 : I客户
{
public I银行业务系统 银行业务系统()
{
return new 转账接口类();
}
}
public interface I银行业务系统
{
void 银行业务系统();
}
public class 存款接口类:I银行业务系统
{
public void 银行业务系统()
{
Console.WriteLine("存款");
}
}
public class 取款接口类 : I银行业务系统
{
public void 银行业务系统()
{
Console.WriteLine("取款");
}
}
public class 转账接口类 : I银行业务系统
{
public void 银行业务系统()
{
Console.WriteLine("转账");
}
}
这样子我们就实现了单一职责原则和开闭原则,我们要习惯于面向抽象编程,抽象抽象再抽象。变化变化再变化。我们封装抽象不是目的,目的就是封装它的变化。俗话说的好:建房子的时候是很累的,可是装修的时候是舒服的!