Java設(shè)計模式之開閉原則精解
1.什么是開閉原則?
- 開閉原則(Open Closed Principle)是編程中最基礎(chǔ)、最重要的設(shè)計原則。
- 一個軟件實體如類,模塊和函數(shù)應(yīng)該對擴展開放(對提供方),對修改關(guān)閉(對使用方)。用抽象構(gòu)建框架,用實現(xiàn)擴展細節(jié)。
- 當(dāng)軟件需要變化時,盡量通過擴展軟件實體的行為來實現(xiàn)變化,而不是通過修改已有的代碼來實現(xiàn)變化。
- 編程中遵循其它原則,以及使用設(shè)計模式的目的就是遵循開閉原則。
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; } } //這是一個用于繪圖的類 [使用方] class GraphicEditor { //接收Shape對象,然后根據(jù)type,來繪制不同的圖形 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) { //使用看看存在的問題 GraphicEditor graphicEditor = new GraphicEditor(); graphicEditor.drawShape(new Rectangle()); graphicEditor.drawShape(new Circle()); } }
根據(jù)上面的代碼及運行結(jié)果來看,沒一點問題,我們?nèi)缭傅漠嫵隽司匦?、圓形。但是現(xià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; } } //這是一個用于繪圖的類 [使用方] class GraphicEditor { //接收Shape對象,然后根據(jù)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(" 繪制三角形 "); } } 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()); } }
對代碼的修改完成了,也按照要求繪制出了三角形。但是大家仔細對比上面這兩段代碼,你會發(fā)現(xiàn):第一,改動的地方偏多;第二,在使用方 GraphicEditor 類中也做了修改。 這就明顯違反了開閉原則中的 對修改關(guān)閉 這個規(guī)則。
我們需要的是 對擴展開放,對修改關(guān)閉 的規(guī)則,也就是說增添一個三角形的時候,我們只需要在提供方做修改,在使用方是無需修改的。
也就是說,當(dāng)我們給一個類增添新的功能時,盡量不修改代碼,或者是盡量少的修改代碼。
3.遵守Ocp代碼案例
思路: 把創(chuàng)建Shape類做成抽象類,并提供一個抽象的draw方法,讓子類去實現(xiàn)即可,這樣我們有新的圖形種類時,只需要讓新的圖形類繼承Shape,并實現(xiàn) draw方法即可,使用方的代碼就不需要修 → 滿足了開閉原則。
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 GraphicEditor { //接收Shape對象,調(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()); } }
上面是改進之后的代碼,此時我們還像之前的案例一樣,增添一個新的圖形(三角形),并完成對三角形的繪制,那么對上面代碼的修改就少之又少了。
修改代碼如下:??????
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(" 繪制三角形 "); } } //這是一個用于繪圖的類 [使用方] class GraphicEditor { //接收Shape對象,調(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()); } }
可以看到,我們對提供方代碼中新增了一個 Triangle 類,它來完成對三角形的繪制。而自始至終我們的使用方 GraphicEditor 類都沒有做任何的修改。
這就自然而然的滿足了開閉原則中的 對擴展開發(fā)、對修改關(guān)閉 了。
到此這篇關(guān)于Java設(shè)計模式之開閉原則精解的文章就介紹到這了,更多相關(guān)Java 開閉原則內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
深入解析StringBuffer和StringBuilder的區(qū)別
以下是對java中StringBuffer與StringBuilder的區(qū)別進行了詳細的分析介紹,需要的朋友可以參考下2013-07-07SSH框架網(wǎng)上商城項目第8戰(zhàn)之查詢和刪除商品類別功能實現(xiàn)
SSH框架網(wǎng)上商城項目第8戰(zhàn)之查詢和刪除商品類別功能實現(xiàn),為項目增加功能,添加、更新、刪除和查詢操作,感興趣的小伙伴們可以參考一下2016-05-05java 實現(xiàn)取int型的第二個字節(jié)的數(shù)
這篇文章主要介紹了java 實現(xiàn)取int型的第二個字節(jié)的數(shù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01BeanUtils.copyProperties()參數(shù)的賦值順序說明
這篇文章主要介紹了BeanUtils.copyProperties()參數(shù)的賦值順序說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09SpringBoot實現(xiàn)ORM操作MySQL的幾種方法
本文主要介紹了SpringBoot實現(xiàn)ORM操作MySQL的幾種方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02Spring Boot JDBC 連接數(shù)據(jù)庫示例
本篇文章主要介紹了Spring Boot JDBC 連接數(shù)據(jù)庫示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02