开闭原则
开闭原则,即如一个软件实体类,模块和函数应该对扩展开发(对提供方),对修改关闭(对使用方),用抽象构建框架,用实现扩展细节。
当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。
下面直接给出未遵循开闭原则的实现代码和遵循开闭原则的实现代码。
未遵循开闭原则的原则的代码
package com.gaoliwei.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());
}
}
//这是一个用于绘图的类
class GraphicEditor{
public void drawShape(Shape s){
if(s.m_type == 1){
drawRectangle();
}else if(s.m_type == 2){
drawCircle();
}else if(s.m_type == 3){
drawTriangle();
}
}
public void drawRectangle(){
System.out.println("绘图长方形");
}
public void drawCircle(){
System.out.println("绘图圆形");
}
public void drawTriangle(){
System.out.println("绘图三角形");
}
}
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;
}
}
运行结果
绘图长方形
绘图圆形
绘图三角形
此种方法虽然能够成功运行程序,但每增加一个图形类时,都需要对绘图类进行修改,增加图形类序号和增加绘图方法。未通过扩展软件实体的行为来实现变化,而是以修改已有的代码来实现变化,因此未实现开闭原则。
已实现开闭原则的代码
package com.gaoliwei.ocp.improve;
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 Other());
}
}
//这是一个用于绘图的类
class GraphicEditor{
//直接调用各个画图类的draw方法就行
public void drawShape(Shape s){
s.draw();
}
}
abstract class Shape{
public abstract void draw();
}
class Rectangle extends Shape {
@Override
public void draw() {
System.out.println("绘制长方形");
}
}
class Circle extends Shape {
@Override
public void draw() {
System.out.println("绘制圆形");
}
}
class Triangle extends Shape {
@Override
public void draw() {
System.out.println("绘制三角形");
}
}
class Other extends Shape{
@Override
public void draw() {
System.out.println("绘制其它图形");
}
}
运行结果
绘制长方形
绘制圆形
绘制三角形
绘制其它图形
此种方法通过定义了一个抽象类的抽象draw()方法,使每一个继承自Shape的图形类都实现draw()方法,又因为每一个类都为Shape类的子类,可以通过对象的多态性传递到drawShape()中,所以也能够实现绘图的效果。
但是此种方法,是通过扩展软件实体的行为来实现变化,而不是通过修改已有代码来实现的变化,所以符合开闭原则。