formatuu 发表于 2015-6-17 08:47:45

面向对象设计原则:开放-封闭原则(OCP)

  ●定义
  软件实体(类、模块、函数等)应该是可以扩展的,但是不可修改的。
  “开放-封闭”原则(The open-Closed Principle)可以说是面向对象设计的核心所在。
  “开放-封闭”原则的两个重要特点是“对扩展开放,对修改关闭”,即允许对程序作出扩展(以扩展的方式响应需求的变化),但拒绝对程序作出修改(即修改之前运行良好的程序)。
  实现“开放-封闭”原则的重要机制就是“抽象”与“多态”。通过对“变化”进行抽象隔离,使程序具有更好的扩展性与可维护性。
  ●以具体的代码演示OCP
  没有遵循OCP原则的示例
  客户将要使用的电脑(方正)
  public class FangZhengComputer
{
public FangZhengComputer()
{
    //...构造函数
}
public string OutCpuInfo()
{
    return "fangzheng's Cpu!" ;
}
//...other Method
}
  客户使用电脑(客户代码)
  FangZhengComputermyComputer = new FangZhengComputer() ;
myComputer.OutCpuInfo() ;
  上面代码中客户使用的是方正电脑。现在,客户要使用联想电脑(需求变化),那我们的程序应该怎么变化?很明显,我们可能会增加一种电脑类型(有人也许会直接将方正电脑改变联想电脑),然后去更改客户端的代码。这样做带来的后果在某些情况下是很难让人接受的。
  遵循OCP原则的示例
  上面的代码其弊端在于:客户端直接依赖于一个具体的实现,当具体实现发生变化时,客户端代码也要发生变化。现在,我们将“变化”的部分(即 new FangZhengComputer() ;)进行抽象隔离。
  首先定义一个抽象类,它是客户使用电脑的基类
  public abstract class Computer
{
   public abstract string OutCpuInfo();
   //other Method
}
  然后定义一个联想电脑类,它从Computer类继承
  public class LianXiangComputer : Computer
{
   public override string OutCpuInfo()
   {
    return "LianXiangComputer's Cpu!" ;
   }
   //other Method
}
  客户端调用:
  Computer myComputer = new Computer () ;
  这时,客户端依赖就不是一个具体的实现了,它依赖的是一个抽象,所以当Computer类的某个子类发生变化时,客户端代码是不需要发生变化的。这样,如果客户今天又要使用宏基电脑,那只需要从Computer 类继承一个子类就可以了,这就是扩展,同时,之前的代码(包括客户端的和已经存在的电脑类型)都不需要发生变化。
  (我们上面的代码不是很完全,可以利用工厂加上配置文件来动态指定所要使用的电脑类型)
页: [1]
查看完整版本: 面向对象设计原则:开放-封闭原则(OCP)