一、原则介绍
开闭原则(Open Closed Principle)是编程中最基础、最重要的设计原则——面向对象设计的终极目标。是面向对象设计中“可复用设计”的基石,是面向对象设计中最重要的原则之一,其它很多的设计原则都是实现开闭原则的一种手段。
开放封闭原则,是说软件实体(类、模块、函数等等)应该可以扩展,但是不可修改。
- 开,是指对于组件功能的扩展是开放的,是允许对其进行功能扩展的
- 闭,是指对于原有代码的修改是封闭的,即不应该修改原有的代码
即当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。用抽象构建框架,用实现扩展细节。
二、举例说明
实现一个画图形的类
class Rectangle{
void draw(){ System.out.println("矩形"); }
}
class Circle {
void draw(){ System.out.println("圆形"); }
}
class GraphicDraw {
void drawgraph(int type){
if(type==1){
Rectangle rec=new Rectangle();
rec.draw();}
else if(type==2){
Circle c=new Circle();
c.draw();}
}
}
public class graphDraw {
public static void main(String[] args) {
GraphicDraw graphicdraw=new GraphicDraw();
graphicdraw.drawgraph(2); //客户端肯定要改
}
}
需要新增一个图形种类,如三角形时
新增图形三角形类
方式1
class Rectangle{
void draw(){ System.out.println("矩形"); }
}
class Circle {
void draw(){ System.out.println("圆形"); }
}
class Triangle { //新增三角形——肯定要改
void draw(){ System.out.println("三角形"); }
}
class GraphicDraw {
void drawgraph(int type){
if(type==1){
Rectangle rec=new Rectangle();
rec.draw();}
else if(type==2){
Circle c=new Circle();
c.draw();}
else if(type==3){ //新增绘制三角形
Triangle t=new Triangle();
t.draw();}
}
}
public class graphDraw {
public static void main(String[] args) {
GraphicDraw graphicdraw=new GraphicDraw();
graphicdraw.drawgraph(3); //客户端肯定要改
}
}
优缺点:
优点是比较好理解,简单易操作。
缺点是违反了开闭原则;需要给类增加新功能的时候,尽量不要修改代码,或者尽可能少修改代码。
改进思路:
发现Rectangle和Circle有共同的draw方法,创建抽象Shape类做成基类,并提供抽象的draw方法,让子类去实现,当需要新的图形时,只需要让新的图形继承Shape,并实现draw方法。画图类GraphicDraw不出现具体的类,用抽象类Shape。这样使用方的代码就不需要修改,满足开闭原则。
方式2:
//Shape类,基类
abstract class Shape {
public abstract void draw(); //抽象方法
}
class GraphicDraw { //新增绘制图形不需修改此类
void drawgraph(Shape s){ s.draw(); }
}
class Rectangle extends Shape {
void draw(){ System.out.println("矩形"); }
}
class Circle extends Shape {
void draw(){ System.out.println("圆形"); }
}
class Triangle extends Shape { //新增三角形
void draw(){ System.out.println("三角形"); }
}
public class graphDraw {
public static void main(String[] args) {
GraphicDraw graphicdraw=new GraphicDraw();
graphicdraw.drawgraph(new Circle());
graphicdraw.drawgraph(new Rectangle());
graphicdraw.drawgraph(new Triangle());
}
}