一、介绍
1)开闭原则(OCP)是编程中最基础也是最重要的设计原则
2)一个软件实体如类,模块和函数应该对扩展开放(提供方),对修改关闭(使用方),用抽象构建框架,用实现扩展细节。
3)当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。
4)编程中使用其他原则,以及设计模式的目的就是遵循开闭原则。
二、应用
假设我们需要实现这样的一个应用:需要客户端选择的几何图形种类来画出相应的图形。
现在程序提供了画出矩形和圆形的两种功能,假设我们还需要添加一个画出三角形的功能,代码如下
public static void main(String[] args) {
GraphicEditor graphicEditor = new GraphicEditor();
graphicEditor.drawShape(new Rectangle());
graphicEditor.drawShape(new Circle());
//graphicEditor.drawShape(new Triangle());
}
}
//这是一个用于绘图的类 [使用方]
class GraphicEditor {
//接收Shape对象,然后根据type,来绘制不同的图形
public void drawShape(Shape s) {
if (s.m_type == 1)
drawRectangle(s);
else if (s.m_type == 2)
drawCircle(s);
//else if (s.m_type == 3)
// drawTriangle(s);
}
//绘制矩形
public void drawRectangle(Shape r) {
System.out.println(" 绘制矩形 ");
}
//绘制圆形
public void drawCircle(Shape r) {
System.out.println(" 绘制圆形 ");
}
//绘制三角形
//public void drawTriangle(Shape r) {
// System.out.println(" 绘制三角形 ");
}
}
//Shape类,基类
class Shape {
int m_type;
}
class Rectangle extends Shape {
Rectangle() {
super.m_type = 1;
}
}
class Circle extends Shape {
Circle() {
super.m_type = 2;
}
//class Triangle extends Shape {
// Triangle() {
// super.m_type = 3;
}
}
注释掉的代码即我们在增加画三角形这一功能时需要增加的代码。
虽然这个代码比较好懂,但是会出现这样的问题:使用端需要使用代码的时候竟然需要亲自增加一段条件判断,很显然这种设计是违反OCP原则的。这样需要修改的代码实在是有点多。
public class Ocp {
public static void main(String[] args) {
GraphicEditor graphicEditor = new GraphicEditor();
graphicEditor.drawShape(new Rectangle());
graphicEditor.drawShape(new Circle());
graphicEditor.drawShape(new Triangle());
graphicEditor.drawShape(new OtherGraphic());
}
}
//这是一个用于绘图的类 [使用方]
class GraphicEditor {
//接收Shape对象,调用draw方法
public void drawShape(Shape s) {
s.draw();
}
}
//Shape类,基类
abstract class Shape {
int m_type;
public abstract void draw();//抽象方法
}
class Rectangle extends Shape {
Rectangle() {
super.m_type = 1;
}
@Override
public void draw() {
// TODO Auto-generated method stub
System.out.println(" 绘制矩形 ");
}
}
class Circle extends Shape {
Circle() {
super.m_type = 2;
}
@Override
public void draw() {
// TODO Auto-generated method stub
System.out.println(" 绘制圆形 ");
}
}
//新增画三角形
class Triangle extends Shape {
Triangle() {
super.m_type = 3;
}
@Override
public void draw() {
System.out.println(" 绘制三角形 ");
}
}
//新增一个图形
class OtherGraphic extends Shape {
OtherGraphic() {
super.m_type = 4;
}
@Override
public void draw() {
System.out.println(" 绘制其它图形 ");
}
}
我们采用这种继承的方法,就无需让使用端来一个个判断应当执行的操作,而是采用这种直接的方式,根据传入的对象类型来执行各自的方法。