设计原则之开闭原则
(1)开闭原则:
开闭原则(Open Closed Principle , OCP)是指“软件实体应当对扩展开发,对修改关闭(Software entities should be open for extension , but close for modification )” 此概念是大牛Bertrand Meyer于1988年提出。
“Open for extension ” 意味着模块的行为是可以扩展的。
“Close for modification” 意味着对模块行为进行扩展时,不必改变模块源代码或二进制代码。
简而言之,开闭原则:可以根据需求随意增加新的类,但是不要修改原有的类。
(2)开闭原则设计系统时的优点:
*可扩展程度高,非常灵活。
*可维护性强,无需改动源代码。
(3)如何实现开闭原则:
实现开闭原则的核心在于“抽象”。系统设计时,要区分哪些是变化的部分,哪些是不变的部分。对不变的部分,可以抽象为不变的接口;对于变化的部分,可以进行评估和分类,每个可变的因素都单独进行封装。
例子:
接口定义:
package org.yjY.ocp.interfaceOcp;
public interface InterfaceShop
{
public String getShoeName();
public String getShoeType();
public int getShoeValue();
}
接口实现:
package org.yjY.ocp.interfaceOcp.impl;
import org.yjY.ocp.interfaceOcp.InterfaceShop;
public class MenShoe implements InterfaceShop
{
private String shoeName;
private String shoeType;
private int shoeValue;
public MenShoe(String shoeName,String shoeType,int shoeValue)
{
this.shoeName = shoeName;
this.shoeType = shoeType;
this.shoeValue = shoeValue;
}
@Override
public String getShoeName()
{
return shoeName;
}
@Override
public String getShoeType()
{
return shoeType;
}
@Override
public int getShoeValue()
{
return shoeValue;
}
}
package org.yjY.ocp.interfaceOcp.impl;
import org.yjY.ocp.interfaceOcp.InterfaceShop;
public class WomenShoe implements InterfaceShop
{
private String shoeName;
private String shoeType;
private int shoeValue;
public WomenShoe(String shoeName,String shoeType,int shoeValue)
{
this.shoeName = shoeName;
this.shoeType = shoeType;
this.shoeValue = shoeValue;
}
@Override
public String getShoeName()
{
return shoeName;
}
@Override
public String getShoeType()
{
return shoeType;
}
@Override
public int getShoeValue()
{
return shoeValue;
}
}
扩展行为:
*男鞋原价大于200元打8折,原价大于150元打8.5折,其他价格一律9折;
*女鞋原价大于200元打7.5折,原价大于150元打8折,其他价格一律8.5折;
实现方案:
一、在接口中增加打折方法用于处理降价,此时两个实现该接口的类(MenShoe , WomenShoe )都必须修改,不符合开闭原则
二、在两个类(MenShoe , WomenShoe )中各增加一个方法,此方案好一些,但不是做好方案
三、增加两个类(MenShoeDiscount , WomenShoeDiscount ),分别用于处理男鞋和女鞋的降价,此方案修改量小,可扩展性强,最符合开闭原则。
package org.yjY.ocp.interfaceOcp.impl;
public class MenShoeDiscount extends MenShoe
{
public MenShoeDiscount(String shoeName, String shoeType, int shoeValue)
{
super(shoeName, shoeType, shoeValue);
}
public int getShoeValue()
{
int shoePrice = super.getShoeValue();
int discount = 0;
if (shoePrice>200)
{
discount = shoePrice*80/100;
}
if (shoePrice>150)
{
discount = shoePrice*85/100;
}
else
{
discount = shoePrice*90/100;
}
return discount;
}
}
package org.yjY.ocp.interfaceOcp.impl;
public class WomenShoeDiscount extends MenShoe
{
public WomenShoeDiscount(String shoeName, String shoeType, int shoeValue)
{
super(shoeName, shoeType, shoeValue);
}
public int getShoeValue()
{
int shoePrice = super.getShoeValue();
int discount = 0;
if (shoePrice>200)
{
discount = shoePrice*75/100;
}
if (shoePrice>150)
{
discount = shoePrice*80/100;
}
else
{
discount = shoePrice*85/100;
}
return discount;
}
}
测试JSP:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" import="org.yjY.ocp.interfaceOcp.impl.*"%>
<html>
<head>
</head>
<body>
<%
MenShoeDiscount msd = new MenShoeDiscount("男鞋名","男鞋类型",160);
out.println("鞋子价格:"+msd.getShoeValue());
%>
</body>
</html>