Java設(shè)計(jì)模式之開(kāi)閉原則精解
1.什么是開(kāi)閉原則?
- 開(kāi)閉原則(Open Closed Principle)是編程中最基礎(chǔ)、最重要的設(shè)計(jì)原則。
- 一個(gè)軟件實(shí)體如類,模塊和函數(shù)應(yīng)該對(duì)擴(kuò)展開(kāi)放(對(duì)提供方),對(duì)修改關(guān)閉(對(duì)使用方)。用抽象構(gòu)建框架,用實(shí)現(xiàn)擴(kuò)展細(xì)節(jié)。
- 當(dāng)軟件需要變化時(shí),盡量通過(guò)擴(kuò)展軟件實(shí)體的行為來(lái)實(shí)現(xiàn)變化,而不是通過(guò)修改已有的代碼來(lái)實(shí)現(xiàn)變化。
- 編程中遵循其它原則,以及使用設(shè)計(jì)模式的目的就是遵循開(kāi)閉原則。
2.違反Ocp代碼案例

package com.szh.principle.ocp;
/**
*
*/
//Shape類,基類
class Shape {
int m_type;
}
class Rectangle extends Shape {
Rectangle() {
super.m_type = 1;
}
}
class Circle extends Shape {
Circle() {
super.m_type = 2;
}
}
//這是一個(gè)用于繪圖的類 [使用方]
class GraphicEditor {
//接收Shape對(duì)象,然后根據(jù)type,來(lái)繪制不同的圖形
public void drawShape(Shape s) {
if (s.m_type == 1)
drawRectangle(s);
else if (s.m_type == 2)
drawCircle(s);
}
//繪制矩形
public void drawRectangle(Shape r) {
System.out.println(" 繪制矩形 ");
}
//繪制圓形
public void drawCircle(Shape r) {
System.out.println(" 繪制圓形 ");
}
}
public class Ocp {
public static void main(String[] args) {
//使用看看存在的問(wèn)題
GraphicEditor graphicEditor = new GraphicEditor();
graphicEditor.drawShape(new Rectangle());
graphicEditor.drawShape(new Circle());
}
}
根據(jù)上面的代碼及運(yùn)行結(jié)果來(lái)看,沒(méi)一點(diǎn)問(wèn)題,我們?nèi)缭傅漠嫵隽司匦?、圓形。但是現(xiàn)在有了一個(gè)新的需求,說(shuō) 要增添一個(gè)圖形(三角形),使代碼完成對(duì)三角形的繪制,那么我們就需要對(duì)上面的代碼進(jìn)行修改。
package com.szh.principle.ocp;
/**
*
*/
//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;
}
}
//這是一個(gè)用于繪圖的類 [使用方]
class GraphicEditor {
//接收Shape對(duì)象,然后根據(jù)type,來(lái)繪制不同的圖形
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(" 繪制三角形 ");
}
}
public class Ocp {
public static void main(String[] args) {
//使用看看存在的問(wèn)題
GraphicEditor graphicEditor = new GraphicEditor();
graphicEditor.drawShape(new Rectangle());
graphicEditor.drawShape(new Circle());
graphicEditor.drawShape(new Triangle());
}
}
對(duì)代碼的修改完成了,也按照要求繪制出了三角形。但是大家仔細(xì)對(duì)比上面這兩段代碼,你會(huì)發(fā)現(xiàn):第一,改動(dòng)的地方偏多;第二,在使用方 GraphicEditor 類中也做了修改。 這就明顯違反了開(kāi)閉原則中的 對(duì)修改關(guān)閉 這個(gè)規(guī)則。
我們需要的是 對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉 的規(guī)則,也就是說(shuō)增添一個(gè)三角形的時(shí)候,我們只需要在提供方做修改,在使用方是無(wú)需修改的。
也就是說(shuō),當(dāng)我們給一個(gè)類增添新的功能時(shí),盡量不修改代碼,或者是盡量少的修改代碼。
3.遵守Ocp代碼案例
思路: 把創(chuàng)建Shape類做成抽象類,并提供一個(gè)抽象的draw方法,讓子類去實(shí)現(xiàn)即可,這樣我們有新的圖形種類時(shí),只需要讓新的圖形類繼承Shape,并實(shí)現(xiàn) draw方法即可,使用方的代碼就不需要修 → 滿足了開(kāi)閉原則。
package com.szh.principle.ocp.improve;
/**
*
*/
//Shape類,基類
abstract class Shape {
int m_type;
public abstract void draw();//抽象方法
}
class Rectangle extends Shape {
Rectangle() {
super.m_type = 1;
}
@Override
public void draw() {
System.out.println(" 繪制矩形 ");
}
}
class Circle extends Shape {
Circle() {
super.m_type = 2;
}
@Override
public void draw() {
System.out.println(" 繪制圓形 ");
}
}
//這是一個(gè)用于繪圖的類 [使用方]
class GraphicEditor {
//接收Shape對(duì)象,調(diào)用draw方法
public void drawShape(Shape s) {
s.draw();
}
}
public class Ocp {
public static void main(String[] args) {
GraphicEditor graphicEditor = new GraphicEditor();
graphicEditor.drawShape(new Rectangle());
graphicEditor.drawShape(new Circle());
}
}
上面是改進(jìn)之后的代碼,此時(shí)我們還像之前的案例一樣,增添一個(gè)新的圖形(三角形),并完成對(duì)三角形的繪制,那么對(duì)上面代碼的修改就少之又少了。
修改代碼如下:??????
package com.szh.principle.ocp.improve;
/**
*
*/
//Shape類,基類
abstract class Shape {
int m_type;
public abstract void draw();//抽象方法
}
class Rectangle extends Shape {
Rectangle() {
super.m_type = 1;
}
@Override
public void draw() {
System.out.println(" 繪制矩形 ");
}
}
class Circle extends Shape {
Circle() {
super.m_type = 2;
}
@Override
public void draw() {
System.out.println(" 繪制圓形 ");
}
}
//新增畫三角形
class Triangle extends Shape {
Triangle() {
super.m_type = 3;
}
@Override
public void draw() {
System.out.println(" 繪制三角形 ");
}
}
//這是一個(gè)用于繪圖的類 [使用方]
class GraphicEditor {
//接收Shape對(duì)象,調(diào)用draw方法
public void drawShape(Shape s) {
s.draw();
}
}
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());
}
}可以看到,我們對(duì)提供方代碼中新增了一個(gè) Triangle 類,它來(lái)完成對(duì)三角形的繪制。而自始至終我們的使用方 GraphicEditor 類都沒(méi)有做任何的修改。
這就自然而然的滿足了開(kāi)閉原則中的 對(duì)擴(kuò)展開(kāi)發(fā)、對(duì)修改關(guān)閉 了。

到此這篇關(guān)于Java設(shè)計(jì)模式之開(kāi)閉原則精解的文章就介紹到這了,更多相關(guān)Java 開(kāi)閉原則內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
深入解析StringBuffer和StringBuilder的區(qū)別
以下是對(duì)java中StringBuffer與StringBuilder的區(qū)別進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以參考下2013-07-07
SSH框架網(wǎng)上商城項(xiàng)目第8戰(zhàn)之查詢和刪除商品類別功能實(shí)現(xiàn)
SSH框架網(wǎng)上商城項(xiàng)目第8戰(zhàn)之查詢和刪除商品類別功能實(shí)現(xiàn),為項(xiàng)目增加功能,添加、更新、刪除和查詢操作,感興趣的小伙伴們可以參考一下2016-05-05
java 實(shí)現(xiàn)取int型的第二個(gè)字節(jié)的數(shù)
這篇文章主要介紹了java 實(shí)現(xiàn)取int型的第二個(gè)字節(jié)的數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
BeanUtils.copyProperties()參數(shù)的賦值順序說(shuō)明
這篇文章主要介紹了BeanUtils.copyProperties()參數(shù)的賦值順序說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
Spring Boot設(shè)置支持跨域請(qǐng)求過(guò)程詳解
這篇文章主要介紹了Spring Boot設(shè)置支持跨域請(qǐng)求過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08
SpringBoot實(shí)現(xiàn)ORM操作MySQL的幾種方法
本文主要介紹了SpringBoot實(shí)現(xiàn)ORM操作MySQL的幾種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02
Spring Boot JDBC 連接數(shù)據(jù)庫(kù)示例
本篇文章主要介紹了Spring Boot JDBC 連接數(shù)據(jù)庫(kù)示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02
java對(duì)同一個(gè)文件進(jìn)行讀寫操作方法
在本篇文章里我們給大家詳細(xì)講述了java對(duì)同一個(gè)文件進(jìn)行讀寫操作的方法和知識(shí)點(diǎn),需要的朋友們可以參考學(xué)習(xí)下。2018-10-10

