开-闭原则:
任何软件在其生命周期内都会发生变化,如果我们期望开发出来的系统不会在第一版之后就被抛弃,就必须面对需求的变化而保持相对稳定.开-闭原则(The open-close principle)为我们提供了指引.
那什么是开-闭原则呢?
软件实体(模块,类,方法等)应该是可以扩展的,但是不可修改的.
这句话说出了软件实体应该具备的两个特征:
1、对扩展式开放的(Open for extension)
当需求变化时,我们可以对模块进行扩展,使其具有满足新需求的新行为。
2、对于更改时封闭的(Closed modification)
对模块进行扩展时,不能修改已有的源代码或二进制代码。
这两个方面似乎是矛盾的,我们怎么才能无需对模块进行改动的情况下改变它的功能呢?
关键是抽象,我们可以把一组行为抽象出一个接口/抽象类,而任意一个可能的行为则表现为
可能的派生类。这个原则的直接结果产生了策略模式(Strategy pattern),策略模式定义了
一个算法的接口,而其派生类则定义了不同的实现。当我们需要新的策略时,我们只需要重新
实现这个接口即可,而其他部分只依赖于这个接口,不依赖具体的实现。
下面我们看看一个使用策略模式满足开闭原则的例子:
public interface Sort<T>{
void sort(T t[]);
}
public class BubbleSort<T> implements BubbleSort<T>{
public void sort(T t[]){
//the bubble sort code
}
}
我们可能需要一个效率更高的算法,而BubbleSort不能够满足我们的需求时,我们不需要修改原来的代码,直接实现一个新的算法来扩展新的功能。
public class QuickSort<T> implements BubbleSort<T>{
public void sort(T t[]){
//the quick sort code
}
}
而其他的代码则只依赖于我们的Sort接口:
class SomeClassUseSort{
private Sort sort;
//other codes
}
下面我们看看Bob大叔举的一个违反OCP的例子:
绘制图形的例子:
class Shape{}
class Circle extends Shape{}
class Square extends Shape{}
class DrawAll{
public void drawAll(List<Shape> shapes){
for(Shape shape : shapes){
if(shape instanceof Circle)
drawCircle();
else if(shape instanceof Square){
drawSquare();
}
}
}
private void drawCircle(){
//draw circle;
}
private void drawSquare(){
//draw square
}
}
当我们需要绘制三角形时,我们需要在ShapeDraw中添加drawTriangle方法
并且需要修改drawAll方法,以便能够绘制三角形。
这个例子违反了开闭原则,我们下面考虑如何重构这个例子:
class Shape{
public abstract void draw();
}
class Circle extends Shape{
public void draw(){
//draw circle
}
}
class Square extends Shape{
public void draw(){
//draw Shape
}
}
class DrawAll{
public void drawAll(List<Shape> shapes){
for(Shape shape : shapes){
shape.draw();
}
}
}
当我们怎加新的图形时,我们只需要继承Shape并实现自己的draw方法即可,而无需
修改DrawAll类。这就是遵循开闭原则的威力。其实大部分违反开闭原则都是过程化
的思想所致,当你发现你的类中充斥着一连串的if语句时,基本上说它违反了开闭原则。
现在我们的代码真的满足开闭原则了么?
那我们再看看吧,新的需求来了,要求我们按照形状的顺序来绘制图形,我们现在的代码
如果不作修改的话显得无能为力了。
好的,那我们再抽象出DrawAll接口:
interface DrawAll{
public abstract void drawAll(List<Shape> shapes);
}
class DrawAllByListIndex implements DrawAll{
public void drawAll(List<Shape> shapes){
for(Shape shape : shapes){
shape.draw();
}
}
}
这样我们可以
class DrawAllByShape implements DrawAll{
public void drawAll(List<Shape> shapes){
sortByShape(shapes);
for(Shape shape : shapes){
shape.draw();
}
}
}
来扩展DrawAll就ok了。
就像我们开始抽象的那样,我们根本没有预测到按照图形顺序绘制的需求,我们也不可能
每个东西都抽象出一个接口,因为这样会产生不必要的复杂性,有点过度设计的味道。所以
我们能做的只是去刺激需求,尽快地了解需求可能的变化,我们可以采用测试驱动的方法,首先构建一个可测试的抽象,并且通常这个可测试的抽象会隔离以后可能要发生的其他种变化。
结论
OCP可以说是面向对象设计的核心,遵循这个原则,可以使系统具有更好的灵活性、重用性和可维护性。但是如果肆无忌惮的使用这个原则,进行过度的抽象同样不是好的做法。正确的做法是仅对频繁发生变化的地方进行抽象,拒绝不成熟的抽象和抽象本身同样重要。
分享到:
相关推荐
设计模式是建立在面向对象原则基础上的。面向对象的设计强调类和对象的组织,以及它们之间的相互作用。面向对象设计模式通过类的抽象、类的组织和类之间的通信来实现面向对象设计的优化。 在C#中实现面向对象设计...
在IT行业中,面向对象设计模式是软件开发中的重要概念,特别是在使用C#这样的面向对象编程语言时。设计模式是经过时间验证的、可重用的解决方案,用来解决在软件设计中经常遇到的问题。本视频教程“C#面向对象设计...
在IT行业中,面向对象设计模式是软件开发中的重要概念,特别是在.NET框架,如C#这样的编程语言中。本文将深入探讨“C#面向对象设计模式纵横谈”视频教程及其源码,帮助开发者理解和掌握这些模式在实际项目中的应用。...
面向对象设计模式与面向对象原则的关系 面向对象设计模式是建立在良好的面向对象设计基础上的。优秀的面向对象设计能够更好地应对需求的变化,并提高代码的复用性。面向对象设计模式不仅关注于类的设计,还强调了...
面向对象设计原则是软件开发中的核心概念,尤其在Java、C++等面向对象编程语言中至关重要。这些原则为创建可维护、可扩展和可重用的代码提供了指导框架。这篇文章将深入探讨面向对象设计原则,并结合设计模式进行...
在面向对象编程中,设计模式帮助我们遵循一些基本原则,以提高代码的灵活性、可维护性和可扩展性。在这个主题中,我们将深入探讨"单件模式"这一重要的创建型设计模式。 单件模式是一种确保一个类只有一个实例,并...
### 面向对象自动化测试框架的研究与设计 #### 摘要与引言 本文主要探讨了面向对象自动化测试框架的设计与实现。随着软件规模的不断扩大,传统的手动测试已经无法满足快速迭代的需求,因此自动化测试成为了提高...
本文将深入探讨C#中的面向对象设计模式及其原则,旨在为程序员提供一个理解和应用这些模式的框架。 首先,我们来理解什么是设计模式。设计模式是一种在特定情况下解决问题的通用、可复用的解决方案,它描述了在软件...
而面向对象的C++设计模式则是将这两种概念巧妙融合,为软件开发提供了强大的工具和框架。下面,我们将深入探讨这些关键知识点。 首先,我们要了解**数据结构**。数据结构是指在计算机中组织和存储数据的方式,以...
本文将深入探讨C#中的核心面向对象概念,以及与之相关的UML(统一建模语言)、设计原则和模式。 1. **dotNet概述** .NET是微软推出的一个开发平台,它提供了丰富的库和服务,支持多种语言(如C#、VB.NET、F#等)...
《清华Java语言与面向对象程序设计》是一门深入讲解Java编程和面向对象设计的课程,旨在帮助学习者掌握Java编程的基础知识以及如何运用面向对象的思想进行软件开发。课程内容覆盖了从基本语法到高级特性,从理论概念...
面向对象设计模式是软件开发中的重要概念,尤其是在C#这样的面向对象编程语言中。设计模式是一种在特定场景下解决问题的标准化解决方案,它来源于实践中并被广泛验证为有效的。本篇文章将深入探讨C#中面向对象设计...
6. **面向对象设计原则与设计模式**:第十六章提供了面向对象设计的原则和常用的设计模式,帮助开发者更好地组织代码和解决实际问题。 #### 特色亮点 与其他同类教材相比,《面向对象程序设计与Java语言》具有以下...
通过PPT的学习材料,我们可以深入探讨每个主题,如“设计模式”可以帮助我们更好地理解和应用常见的软件设计解决方案,“UML介绍”让我们掌握统一建模语言,用于系统分析和设计,“面向对象设计原则”如单一职责、开...
### 设计模式基础培训材料-面向对象设计原则与模式 ...以上概述了面向对象设计的基本原则以及23种设计模式,并通过Qt框架中的实例进行了简要说明。理解和应用这些原则和模式对于构建高质量的软件系统至关重要。
总结来说,"面向对象分析与设计"主题涵盖了大量的理论知识和实践经验,包括面向对象的基本概念、设计原则、设计模式以及在Java项目中的实际应用。通过学习相关书籍和研究实际项目源码,开发者可以提升自己的面向对象...
6.恰恰是告诉我们用抽象构建框架,用实现扩展细节的注意事项而已:单一职责原则告诉我们实现类要职责单一;里氏替换原则告诉我们不要破坏继承体系;依赖倒置原则告诉我们要面向接口编程;接口隔离原则告诉我们在设计...
本系列视频教程旨在通过12天的学习与实践,帮助开发者掌握如何使用PHP语言构建一个面向对象的自定义MVC框架,并应用到实际项目中。 #### 二、MVC架构基础 1. **MVC概述** - **模型(Model)**:负责处理应用程序的...