day03_面向对象五大原则_基石_开闭原则

1988年,勃兰特·梅耶(Bertrand Meyer)在他的著作《面向对象软件构造(Object Oriented Software
Construction)》中提出了开闭原则,它的原文是这样:“Software entities should be open for extension,but closed for modification”。翻译过来就是:“软件实体应当对扩展开放,对修改关闭”。这句话说得略微有点专业,我们把它讲得更通俗一点,也就是:软件系统中包含的各种组件,例如模块(Modules)、(Classes)以及功能(Functions)等等,应该在不修改现有代码的基础上,引入新功能。开闭原则中“开”,是指对于组件功能的扩展是开放的,是允许对其进行功能扩展的;开闭原则中“闭”,是指对于原有代码的修改是封闭的,即不应该修改原有的代码。

----百度百科

为什么没有说是面向对象6大原则,为什么没有将开闭原则包括进去?

开闭原则是最基础的一个原则,前面5个原则就是它的具体形态,开闭原则才是他们的接口。

IBook作为一个接口,里面有三个方法,而小说NovelBook是一个具体的实现类,是所有小说的总称,BookStore指的是书店。

public interface IBook {
 public String getName();
 public int getPrice();
 public String getAuthor();
}
public class NovelBook implements IBook {
 private String name;
 private int price;
 private String autor;

 public NovelBook(String name,int price,String autor){
  this.name=name;
  this.price=price;
  this.autor=autor;
 }

 public String getAuthor() {
  return this.autor;
 }

 public String getName() {
  return this.name;
 }

 public int getPrice() {
  return this.price;
 }
}
public class Store {

 private final static ArrayList<IBook> booklist = new ArrayList<IBook>();

 static { // 静态模块加载数据,实际项目一般由持久层完成
  booklist.add(new NovelBook("巴黎圣母院", 3200, "雨果"));
  booklist.add(new NovelBook("悲惨世界", 5600, "雨果"));
  booklist.add(new NovelBook("天龙八部", 4800, "金庸"));
  booklist.add(new NovelBook("挪威的森林", 2200, "村上春树"));
 }

 public static void main(String[] args) {
  NumberFormat format = NumberFormat.getCurrencyInstance();
  format.setMaximumFractionDigits(2);

  System.out.println("-------------书店卖出去的书籍记录如下---------------");
  for (IBook book : booklist) {
   System.out.println("书籍名称:" + book.getName() + "\t书籍作者:"
     + book.getAuthor() + "\t书籍价格:"
     + format.format(book.getPrice() / 100.0) + "元");
  }
 }
}

让程序猿最害怕的需求变化来了: 因为俺们村最近炒股,都赔了,书卖不出去,需要打折来促销,40块以上的9折,以下的8折。

思考如何修改:

1.一了百了,修改接口,如果这个需求变化在设计的时候就想到了就好了。这样修改的话下面的NovelBook类要改,书店类也要改。接口对外是承诺,一旦确认不能修改。不能经常变化。否定!

2.修改NovelBook中的getPrice方法,替换class文件,这个可行。但是还要结合实际情况。待定!

3.扩展一个子类,重写getPrice方法。   可以!

public class OffNovelBook extends NovelBook {

 public OffNovelBook(String name, int price, String autor) {
  super(name, price, autor);
 }
 @Override
 public int getPrice() {
  int price=super.getPrice();
  int oprice=0;
  if(price>4000){
   oprice= price*90/100;
  }else{
   oprice= price*80/100;
  }
  return oprice;
 }
}
static { // 静态模块加载数据,实际项目一般由持久层完成
  booklist.add(new NovelBook("巴黎圣母院", 3200, "雨果"));
  booklist.add(new NovelBook("悲惨世界", 5600, "雨果"));
  booklist.add(new NovelBook("天龙八部", 4800, "金庸"));
  booklist.add(new NovelBook("挪威的森林", 2200, "村上春树"));
  booklist.add(new OffNovelBook("唐诗三百首", 4500, "谁写的"));
 }

也许有人会认为高层业务代码已经修改了,但是这是不可避免的,有的时候甚至会连界面也会修改的。 变化也许是逻辑变化,也许是子模块变化,那么相应的对于其他模块必然会造成影响,视图变化也需要扩展。

再说了,如果你修改了以前写好的代码,要知道,在实际开发中,投入的代码都是经过测试MM的千锤百炼的,如果你这一改,测试MM的笑脸你是别想再看到了。不改的话我们还是好朋友。

开闭原则的好处:

1.测试

2.复用性

3.可维护性

总之一句话,拥抱变化,拒绝修改,提倡扩展。系统的稳定性得到了保证。

让程序猿最害怕的需求又变化来了: 现在俺们村文化程度提高了,书店需要扩展,前几天张家的儿子和李家的女儿都考上了计算机专业,一个是大数据,一个是嵌入式,我们要加这俩个领域的书

如何思考: 需要增加一个属性领域,还得在原来的基础上扩展,不能修改原有的抽象层,那么我再加一个不就行了吗? 让IComputer接口继承IBook接口,然后再写具体类。通过构造传参。

public interface IComputerBook extends IBook {
 public String getScope();
}
public class ComputerBook implements IComputerBook {
 private String name;
 private int price;
 private String autor;
 private String scope;

 public ComputerBook(String name, int price, String autor, String scope) {
  this.name = name;
  this.price = price;
  this.autor = autor;
  this.scope = scope;
 }

 public String getScope() {
  return this.scope;
 }

 public String getAuthor() {
  return this.autor;
 }

 public String getName() {
  return this.name;
 }

 public int getPrice() {
  return this.price;
 }
}
static { // 静态模块加载数据,实际项目一般由持久层完成
  booklist.add(new NovelBook("巴黎圣母院", 3200, "雨果"));
  booklist.add(new NovelBook("悲惨世界", 5600, "雨果"));
  booklist.add(new NovelBook("天龙八部", 4800, "金庸"));
  booklist.add(new NovelBook("挪威的森林", 2200, "村上春树"));
  booklist.add(new OffNovelBook("下架的书", 4500, "谁写的"));
  booklist.add(new ComputerBook("大数据入门", 8500, "李老师", "大数据"));
  booklist.add(new ComputerBook("嵌入式精髓", 2600, "吴老师", "嵌入式"));
 }

这样的设计遵循抽象约束原则:   1.通过抽象层约束扩展,对扩展进行边界限定。

2.参数类型,引用对象尽量使用接口或者抽象类。

3.抽象层始终维持稳定,一旦确定不再修改。

1.抽象约束

2.元数据控制模板

元数据: 配置参数,变化的参数,例如登录时需要先检查IP地址,然后决定是否登录,SSH使用了拦截器,这在之前的博客有写过。控制反转,使用底层的反射来写的。

3.制定项目章程

所有成员必须遵守的约定,整齐划一,提高开发效率,这个目前只能是模拟幻想而已。。。

4.封装变化

(1).将相同的变化封装到一个接口或抽象类中。  (2).将不同的变化封装到不同的接口或者抽象类中。

参考书籍《设计模式之禅》

我是菜鸟,我在路上。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-16 17:23:26

day03_面向对象五大原则_基石_开闭原则的相关文章

面向对象的基本原则(二)------开闭原则

一.定义 开闭原则(OCP),英文全称是Open for extention, Closed for modification Principle,即对扩展开放,对修改关闭原则.该原则的思想是,可以通过扩展来满足变化,而不需要修改代码,或者说在设计一个模块的时候,应当使这 个模块可以在不被修改的前提下被扩展. 二.实现 实现开闭原则的关键是抽象,抽象是面向对象设计的一个核心特征. 对一个事物抽象化,实质上是在概括归纳总结它的本质.抽象让我们抓住最最重要的东西,从更高一层去思考,这降低了思考的复杂

设计模式六大原则(6)--开闭原则

定义: 软件中的对象(类,模块,函数等等)应该对于扩展是开放的,但是对于修改是封闭的. 个人理解: 开闭原则通俗的来说就是软件系统中包含的各种组件,例如模块(Modules).类(Classes)以及功能(Functions)等等,应该在不修改现有代码的基础上,引入新功能.开闭原则中“开”,是指对于组件功能的扩展是开放的,是允许对其进行功能扩展的:开闭原则中“闭”,是指对于原有代码的修改是封闭的,即不应该修改原有的代码. 问题由来: 在软件的生命周期内,由于需求变动.维护和升级需要对项目部分代码

设计模式七大原则(一)开闭原则

设计模式七大原则--开闭原则 1.1 定义: 一个软件实体如类.模块和函数应该对扩展开放,对修改关闭. 用抽象构建框架,用实体扩展细节. 1.2 优点: 提高软件系统的可复用性及可维护性. 1.3 问题由来: 在软件的生命周期中,因为变化.升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码引入错误,也可能会使我们不得不对整个功能进行重构,并且需要原有代码进过重新测试. 1.4 解决方案: 当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化. 实现

面向对象五大原则_基石_开闭原则

1988年,勃兰特·梅耶(Bertrand Meyer)在他的著作<面向对象软件构造(Object Oriented Software Construction)>中提出了开闭原则,它的原文是这样:"Software entities should be open for extension,but closed for modification". 翻译过来就是:"软件实体应当对扩展开放.对改动关闭". 这句话说得稍微有点专业,我们把它讲得更通俗一点,

Python:面向对象的“开闭原则”和“鸭子类型”

开闭原则 开闭原则(OCP)是面向对象设计中"可复用设计"的基石,是面向对象设计中最重要的原则之一,其它很多的设计原则都是实现开闭原则的一种手段. 1988年,勃兰特·梅耶(Bertrand Meyer)在他的著作<面向对象软件构造(Object Oriented Software Construction)>中提出了开闭原则,它的原文是这样:"Software entities should be open for extension,but closed fo

面向对象设计原则之开闭原则

http://blog.csdn.net/lovelion/article/details/7537584 为了满足开闭原则,需要对系统进行抽象化设计,抽象化是开闭原则的关键.在Java.C#等编程语言中,可以为系统定义一个相对稳定的抽象层,而将不同的实现行为移至具体的实现层中完成.在很多面向对象编程语言中都提供了接口.抽象类等机制,可以通过它们定义系统的抽象层,再通过具体类来进行扩展.如果需要修改系统的行为,无须对抽象层进行任何改动,只需要增加新的具体类来实现新的业务功能即可,实现在不修改已有

五大设计原则之(三)--------开闭原则

开闭原则(OCP)是面向对象设计中“可复用设计”的基石,是面向对象设计中最重要的原则之一,其它很多的设计原则都是实现开闭原则的一种手段. 开闭原则的定义: 一个软件实体如类,模块和函数应该对扩展开放,对修改关闭. 遵循开闭原则设计出的模块具有两个主要特征: (1)对于扩展是开放的(Open for extension).这意味着模块的行为是可以扩展的.当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为.也就是说,我们可以改变模块的功能. (2)对于修改是关闭的(Closed

.NET 高级架构师 架构师之路(5)---开闭原则

2 开闭原则(Open-Closed Principle,OCP) 2.1 什么是开闭原则     开闭原则是面向对象设计中"可复用设计"的基石,是面向对象设计中最重要的原则之一,其它很多的设计原则都是实现开闭原则的一种手段. 1988年,Bertrand Meyer在他的著作<Object Oriented Software Construction>中提出了开闭原则,它的原文是这样:"Software entities should be open for e

设计模式原则之开闭原则

开闭原则(OCP)是面向对象设计中“可复用设计”的基石,是面向对象设计中最重要的原则之一,其它很多的设计原则都是实现开闭原则的一种手段. 遵循开闭原则设计出的模块具有两个主要特征: (1)对于扩展是开放的(Open for extension).这意味着模块的行为是可以扩展的.当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为.也就是说,我们可以改变模块的功能. (2)对于修改是关闭的(Closed for modification).对模块行为进行扩展时,不必改动模块的源