标签:开发 软件 没有 ima 文件中 可能性 getname logs .net
一个软件实体如类,模块和函数应该对扩展开放,对修改关闭。
开闭原则明确的告诉我们:软件实现应该对扩展开放,对修改关闭,其含义是说一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化的。那什么是软件实体呢?软件实体包括以下几个部分:
我们举例说明什么是开闭原则,以书店销售书籍为例,其类图如下:
书籍接口:
public interface IBook{ public String getName(); public String getPrice(); public String getAuthor(); }
小说类书籍:
public class NovelBook implements IBook{ private String name; private int price; private String author; public NovelBook(String name,int price,String author){ this.name = name; this.price = price; this.author = author; } public String getAutor(){ return this.author; } public String getName(){ return this.name; } public int getPrice(){ return this.price; } }
Client类:
public class Client{ public static void main(Strings[] args){ IBook novel = new NovelBook("笑傲江湖",100,"金庸"); System.out.println("书籍名字:"+novel.getName()+"书籍作者:"+novel.getAuthor()+"书籍价格:"+novel.getPrice()); } }
项目投产生,书籍正常销售,但是我们经常因为各种原因,要打折来销售书籍,这是一个变化,我们要如何应对这样一个需求变化呢?
我们有下面三种方法可以解决此问题:
在IBook接口中,增加一个方法getOffPrice(),专门用于进行打折处理,所有的实现类实现此方法。但是这样的一个修改方式,实现类NovelBook要修改,同时IBook接口应该是稳定且可靠,不应该经常发生改变,否则接口作为契约的作用就失去了。因此,此方案否定。
修改实现类
修改NovelBook类的方法,直接在getPrice()方法中实现打折处理。此方法是有问题的,例如我们如果getPrice()方法中只需要读取书籍的打折前的价格呢?这不是有问题吗?当然我们也可以再增加getOffPrice()方法,这也是可以实现其需求,但是这就有二个读取价格的方法,因此,该方案也不是一个最优方案。
通过扩展实现变化
我们可以增加一个子类OffNovelBook,覆写getPrice方法。此方法修改少,对现有的代码没有影响,风险少,是个好办法。
下面是修改后的类图:
打折类:
public class OffNovelBook implements NovelBook{ public OffNovelBook(String name,int price,String author){ super(name,price,author); } //覆写价格方法,当价格大于40,就打8析,其他价格就打9析 public int getPrice(){ if(this.price > 40){ return this.price * 0.8; }else{ return this.price * 0.9; } } }
现在打折销售开发完成了,我们只是增加了一个OffNovelBook类,我们修改的代码都是高层次的模块,没有修改底层模块,代码改变量少,可以有效的防止风险的扩散。
我们可以把变化归纳为二种类型:
逻辑变化
只变化了一个逻辑,而不涉及其他模块,比如一个算法是a*b*c,现在需要修改为a+b+c,可以直接通过修改原有类中的方法的方式来完成,前提条件是所有依赖或关联类都按照相同的逻辑处理
子模块变化
一人模块变化,会对其它的模块产生影响,特别是一个低层次的模块变化必然引起高层模块的变化,因此在通过扩展完成变化。
第一:抽象约束
抽象是对一组事物的通用描述,没有具体的实现,也就表示它可以有非常多的可能性,可以跟随需求的变化而变化。因此,通过接口或抽象类可以约束一组可能变化的行为,并且能够实现对扩展开放,其包含三层含义:
第三:制定项目章程
在一个团队中,建立项目章程是非常重要的,因为章程是所有人员都必须遵守的约定,对项目来说,约定优于配置。这比通过接口或抽象类进行约束效率更高,而扩展性一点也没有减少。
第四:封装变化
对变化封装包含两层含义:
(1)将相同的变化封装到一个接口或抽象类中
(2)将不同的变化封装到不同的接口或抽象类中,不应该有两个不同的变化出现在同一个接口或抽象类中。
封装变化,也就是受保护的变化,找出预计有变化或不稳定的点,我们为这些变化点创建稳定的接口。
标签:开发 软件 没有 ima 文件中 可能性 getname logs .net
原文地址:http://www.cnblogs.com/jiansen/p/7343953.html