开闭原则的意思是软件实体应该对扩展开发,对修改关闭(Software entities should be open for extension,but closed for modification)。实现开闭原则的途径是抽象,将需要扩展的部分抽象出来,并留出扩展接口。打个比方,比如电脑机箱上有usb的插口,这些插口就是可扩展的部分,我们可以在这些usb插口上插上鼠标,键盘,U盘,还可以插上网银的U盾等等。电脑硬件上对于usb接口的这个设计就是一个符合开闭原则的设计。
为什么要遵循开闭原则呢?因为开闭原则可以使软件系统更容易复用,更容易维护,当某个软件实体,不适合了,我可以重新做另外一种实现,并将现有的实现替换掉。比如说统计个税的算法发生了一些变化,我可以在不改变原有代码的情况下,重新实现一个算法将原有的算法替换下来。比如说杀毒软件,在出现一种新的病毒时,开发出一个查杀这种病毒的新模块,可以只开发更新这个查杀模块,而不需要改变原有系统的内容。
开闭原则这么好,如何实现符合开闭原则的软件系统呢?答案是抽象,将可能发生变化的功能点进行抽象,并留出变化的接口。设计模式中很多模式都可以帮我们实现开闭原则,个人的理解设计模式是对抽象用法的一种总结。其实我们在项目已经为开闭原则做了一些工作了,比如说我们进行三层开发,将数据层抽象出来,并定义个数据处理的接口,我们可以通过新开发一个数据层把刚开始将数据存放到sql server中的实现,修改为将数据存放到my sql中的实现;我们将业务逻辑中的代码从UI代码中分离出来,这就为我们复用业务逻辑的代码提供了可能,我们可以开发一个专门为手机使用的UI层出来,当用户用手机访问我们的系统时,智能的切换到手机UI层的代码上去执行。
实现开闭原则的例子,其实我都不好意思自己举例子了,因为我正在使用office 2007写这篇博客,在Office2007的快捷工具栏中就有一项是加载项,就是说Office 2007能将插件加载进来使用,如下图所示:
Snagit在word中添加了一个插件,这种插件技术就是一种遵循OCP的实现;再说我们整天使用的Visual Studio 它的可扩展程度更高,可以开发很多类型的工具对他进行扩展。
为了本文的完整性,我还是厚着脸皮,用重构的方式举一个遵循开闭原则的微不足道的实现。
下面的举例实现的场景是个税的计算:我的第一个版本是这样子的
class Program
{
static void Main(string[] args)
{
float salary = 10000;
Console.WriteLine("收入是{0}的人应缴个税是{1},",salary, GetTax(salary));
}
static float GetTax(float salary)
{
return (float)(salary * 0.03);
}
}
这个版本中我未做任何抽象,直接调用静态方法算了,可是一不小心开两会了,个税要调整了,于是个税的算法要进行调整了,怎么办呢,因为要少缴税,我很高兴的就要来重构上面的代码了,既然个税的计算方法是一个变化的东西,我就把它抽象出来吧。
class Program
{
static void Main(string[] args)
{
float salary = 10000;
Console.WriteLine("收入是{0}的人应缴个税是{1},",salary, GetTax(salary));
}
static float GetTax(float salary)
{
ITaxCalculateStrategy strategy = GetTaxCalculateStrategy();
return strategy.GetTax(salary);
}
/// <summary>
/// 获得应该使用的个税计算方法
/// </summary>
/// <returns>个税计算方法实现实例</returns>
static ITaxCalculateStrategy GetTaxCalculateStrategy() {
string typeName = ConfigurationManager.AppSettings["TaxCalculateStrategyType"];
if (string.IsNullOrEmpty(typeName))
throw new ConfigurationErrorsException("请配置TaxCalculateStrategyType");
Type type = Type.GetType(typeName);
if (type == null) throw new ConfigurationErrorsException("TaxCalculateStrategyType错误");
return (ITaxCalculateStrategy)Activator.CreateInstance(type);
}
}
/// <summary>
/// 定义个税计算的接口
/// </summary>
public interface ITaxCalculateStrategy
{
float GetTax(float salary);
}
/// <summary>
/// 两会前个税计算办法的实现
/// </summary>
public class TaxCalculateBefore2Conference : ITaxCalculateStrategy
{
float ITaxCalculateStrategy.GetTax(float salary)
{
return (float)(salary * 0.03);
}
}
/// <summary>
/// 两会后个税的计算方法
/// </summary>
public class TaxCalculateAfter2Conference:ITaxCalculateStrategy
{
float ITaxCalculateStrategy.GetTax(float salary)
{
return (float)(salary * 0.020);
}
}
因为要少缴税,所以我很愉快的重构了之前的代码,可以转眼两会开完了,结果并非如我预期的个税变化,咋办呢?没关系我们重新开发一个个税计算方法,修改下配置就可以仍旧使用之前的个税计算办法了。
开闭原则实现的关键点在于抽象,也许我们刚开始不知道该把那部分抽象出来,但是这并不是问题,我们可以遵循简单设计的原则,当变化来了的时候,再重构代码,做到一种满足开闭原则的设计。
切忌到处都抽象,如果到处都抽象就会导致系统过度设计,过度复杂。这反而是不利于系统的维护。完全的开闭原则是不可能实现的,所以请保持简单设计,在需要的时候做符合开闭原则的设计。
分享到:
相关推荐
开闭原则(Open-Closed Principle,简称OCP)是面向对象设计中的一个核心原则,它在软件工程领域具有举足轻重的地位。该原则由 Bertrand Meyer 在其著作《Object-Oriented Software Construction》中提出,旨在提高...
2. 开闭原则(Open/Closed Principle, OCP):软件实体应当对扩展开放,对修改关闭。这意味着软件系统应该能够在不修改现有代码的基础上进行功能的扩展。 3. 里氏替换原则(Liskov Substitution Principle, LSP):...
开闭原则(Open-Closed Principle,简称OCP)是软件设计模式中的一个基本原则,由艾兹格·迪米特里斯·伯纳斯-李提出。这个原则指出,软件实体(类、模块、函数等)应当对扩展开放,对修改关闭。换句话说,当软件...
面向对象 设计原则 单一职责原则--SRP 开放封闭原则--OCP Liskov替换原则--LSP 依赖倒置原则--DIP 接口隔离原则--ISP
开闭原则(Open-Closed Principle,OCP)是软件工程中的一个基本原则,由Bertrand Meyer在1988年提出,它是面向对象设计的核心之一。这个原则规定了软件实体(如类、模块、函数等)应该对扩展开放,对修改关闭。这...
在软件开发中,开闭原则是面向对象设计中最基础的设计原则之一,它指导我们如何建立稳定灵活的系统。开闭原则定义:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。然而,开闭原则仅仅告诉我们对扩展开放...
开闭原则是面向对象设计中的一个核心原则,它在JAVA设计模式中占据着重要的地位。这一原则由格里·贝斯提出,旨在指导开发者如何设计可维护和可扩展的软件系统。开闭原则(Open-Closed Principle,OCP)的核心思想是...
本节内容主要介绍了面向对象类的设计原则,包括 SRP(单一职责原则)、OCP(开闭原则)、LSP(Liskov 替换原则)、DIP(依赖反转原则)和 ISP(接口隔离原则)。 SRP(单一职责原则) SRP 原则的主要内容是:一个...
首先,让我们了解面向对象设计的基本原则,它们包括单一职责原则(SRP)、开闭原则(OCP)、里氏替换原则(LSP)、接口隔离原则(ISP)、依赖倒置原则(DIP)。这些原则指导我们如何编写高质量的、易于维护的代码。 1. 单一...
Java 设计模式中的 OCP 开闭原则 在软件设计中,OCP 开闭原则是其中一个非常重要的设计原则。该原则定义了一个软件实体,如类、模块和函数应该对扩展开放,对修改关闭。也就是说,当软件需要变化时,应该尽量通过...
以下将详细介绍面向对象设计的六大原则:单一职责原则(Single Responsibility Principle, SRP)、开放封闭原则(Open-Closed Principle, OCP)、里氏替换原则(Liskov Substitution Principle, LSP)、依赖倒置原则...
设计时需遵循一些基本原则,如单一职责原则(SRP)、开闭原则(OCP)、里氏替换原则(LSP)、接口隔离原则(ISP)和依赖倒置原则(DIP),它们有助于提高代码的可读性、可扩展性和可维护性。 “实用面向对象软件...
面向对象设计原则是软件开发中至关重要的一环,它关乎到代码的可维护性、扩展性和复用性。本文将深入探讨这些原则,并结合实例来解释它们的重要性。 首先,我们需要理解面向对象不仅仅是编程语言中的概念,如封装、...
本文将深入探讨其中的两个核心原则:“开-闭”原则(Open-Closed Principle, OCP)和里氏代换原则(Liskov Substitution Principle, LSP)。 首先,我们来详细解析“开-闭”原则(OCP)。该原则由Bertrand Meyer...
面向对象设计模式是软件开发中的重要工具,它们是经过时间考验和广泛实践验证的设计解决方案,旨在提高代码的可重用性、灵活性和可维护性。...因此,学习和掌握面向对象设计模式是每个C#程序员必备的技能之一。
2. **开闭原则(OCP)**:设计的组件应该是对扩展开放,对修改关闭的。这意味着当需要添加新功能时,我们应该尽量避免修改已有的代码,而是通过扩展接口或继承来实现。这有助于保持原有代码的稳定性和可维护性。 3....