1. 程式人生 > >連載:面向物件葵花寶典:思想、技巧與實踐(39)

連載:面向物件葵花寶典:思想、技巧與實踐(39)

又是設計原則,又是設計模式,到底該用哪個呢? =============================================================================

在“設計模型”一章中,我們提到設計原則和設計模式是互補的,設計原則和設計模式互補體現在:設計原則主要用於指導“類的定義”的設計,而設計模式主要用於指導“類的行為”的設計。

舉一個很簡單的例子:假設我們要設計一個圖形類Shape,這個類既支援三角形,又支援矩形,其程式碼如下:

package com.oo.designpattern.diagram;

/**
 * 設計不好的Shape類,同時兼顧三角形和矩形的職責,不符合SRP設計原則
 *
 */
public class BadShape {

    //三角形的屬性
    Position a;
    Position b;
    Position c;
    
    //矩形的屬性
    Position m;
    int length;
    int width;
    
    public void drawTriangle(){
        //TODO: 畫出三角形
    }
    
    public void drawRectangle(){
        //TODO: 畫出矩形
    }
}

有經驗的朋友都會覺得這個設計不太合理,因為其不符合類的SRP設計原則。因此,合理的做法是將這個類按照SRP原則拆分,具體拆分方法如下:

NormalShape.java

package com.oo.designpattern.diagram;

/**
 * 將BadShape拆開為三角形和矩形兩個圖形,並提取出NormalShape這個父類
 *
 */
abstract class NormalShape {
    abstract void draw();
}

NormalTriangle.java

package com.oo.designpattern.diagram;

/**
 * 三角形類
 *
 */
public class NormalTriangle extends NormalShape {
   
    //三角形的屬性
    Position a;
    Position b;
    Position c;
    
    @Override
    public void draw() {
        // TODO:繪畫三角形
        if(Config.CURRENT_SYSTEM == Config.WINDOWS){
            //TODO: 呼叫Windows的畫圖方法
        }
        else if( Config.CURRENT_SYSTEM == Config.LINUX){
            //TODO: 呼叫Linux的畫圖方法
        }
        else if( Config.CURRENT_SYSTEM == Config.MAC){
            //TODO: 呼叫Mac的畫圖方法
        }
    }

}

NormalRectangle.java

package com.oo.designpattern.diagram;

/**
 * 矩形類
 *
 */
public class NormalRectangle extends NormalShape {

    //矩形的屬性
    Position m;
    int length;
    int width;
    
    @Override
    public void draw() {
        // TODO: 繪畫矩形
        if(Config.CURRENT_SYSTEM == Config.WINDOWS){
            //TODO: 呼叫Windows的畫圖方法
        }
        else if( Config.CURRENT_SYSTEM == Config.LINUX){
            //TODO: 呼叫Linux的畫圖方法
        }
        else if( Config.CURRENT_SYSTEM == Config.MAC){
            //TODO: 呼叫Mac的畫圖方法
        }
    }

}


這樣拆分之後,從類的設計原則來看,已經是符合要求了。

接下來我們再使用設計模式來繼續完善這個設計,這裡就需要使用設計模式之道來指導我們設計了,即:找到變化,封裝變化

關於圖形類一個比較明顯的變化是跨平臺,比如說要同時支援Windows、Linux、Mac三個桌面作業系統,那麼實際畫圖的方法和需要呼叫的函式可能就隨著平臺的不同而變化,因此我們要找出一種方法來封裝這種變化。

參考《設計模式》,可以知道這種方法就是“Bridge模式”,使用了Bridge後,會多出幾個介面和實現類。

具體實現如下:

GoodShape.java

package com.oo.designpattern.diagram;

/**
 * 在NormalShape的基礎上,增加Bridge設計模式的實現,使其更加適應於跨平臺
 *
 */
abstract public class GoodShape {

    protected ShapeDraw _draw;  //將不同平臺的實現封裝到一個新的介面ShapeDraw
    abstract void draw();
}


GoodTriangle.java

package com.oo.designpattern.diagram;

/**
 * 按照Bridge設計模式設計的三角形類
 *
 */
public class GoodTriangle extends GoodShape {

    GoodTriangle(ShapeDraw draw){
        this._draw = draw;
    }
    
    @Override
    void draw() {
        // TODO Auto-generated method stub
        this._draw.drawTriangle();
    }

}

GoodRectangle.java

package com.oo.designpattern.diagram;

/**
 * 按照Bridge設計模式設計的矩形類
 *
 */
public class GoodRectangle extends GoodShape {

    GoodRectangle(ShapeDraw draw){
        this._draw = draw; 
    }
    
    @Override
    void draw() {
        // TODO Auto-generated method stub
        this._draw.drawRectangle();
    }

}

ShapeDraw.java

package com.oo.designpattern.diagram;

/**
 * 按照Bridge設計模式進行設計的畫圖的介面,封裝了跨平臺不同的實現
 *
 */
interface ShapeDraw {

    public void drawTriangle();
    public void drawRectangle();
}

WindowsDraw.java

package com.oo.designpattern.diagram;

/**
 * Windwos上的畫圖實現
 *
 */
public class WindowsDraw implements ShapeDraw {

    @Override
    public void drawTriangle() {
        // TODO Auto-generated method stub

    }

    @Override
    public void drawRectangle() {
        // TODO Auto-generated method stub

    }

}

LinuxDraw.java

package com.oo.designpattern.diagram;

/**
 * Linux上的畫圖實現
 *
 */
public class LinuxDraw implements ShapeDraw {

    @Override
    public void drawTriangle() {
        // TODO Auto-generated method stub

    }

    @Override
    public void drawRectangle() {
        // TODO Auto-generated method stub

    }

}

MacDraw.java

package com.oo.designpattern.diagram;

/**
 * Mac上的畫圖實現
 *
 */
public class MacDraw implements ShapeDraw {

    @Override
    public void drawTriangle() {
        // TODO Auto-generated method stub

    }

    @Override
    public void drawRectangle() {
        // TODO Auto-generated method stub

    }

}

可以看到,按照設計原則和設計模式進行重構後,原來不合理的設計逐步演變為一個優秀的設計了

================================================ 
轉載請註明出處:http://blog.csdn.net/yunhua_lee/article/details/38655873
================================================ 

相關推薦

連載面向物件葵花思想技巧實踐39

又是設計原則,又是設計模式,到底該用哪個呢? =============================================================================在

連載面向物件葵花思想技巧實踐20

你知道麼,用例圖 不是 用來描述 用例的哦!!!!熟悉UML的朋友都肯定知道,UML有一個叫做用例圖的東東。單純從名字上來看,你可能以為用例圖是用來描述用例的,即:用例圖 = 用例的圖形化表示。然而各位

連載面向物件葵花思想技巧實踐34

DIP,dependency inversion principle,中文翻譯為“依賴倒置原則”。DIP是大名鼎鼎的Martin大師提出來的,他在1996 5月的C++ Reporter發表“ The 

連載面向物件葵花思想技巧實踐21

用例圖是用來描述系統的,而SSD(系統序列圖)又是來描述用例的,oh my god,這不是在玩我們麼?System Sequence Diagram,縮寫為SSD(注意不要與SSD硬碟混淆),中文翻譯為

連載面向物件葵花思想技巧實踐29

高內聚低耦合,可以說是每個程式猿,甚至是編過程式,或者僅僅只是在大學裡面學過計算機,都知道的一個簡單的設計原則。雖然如此流行和人所眾知,但其實真正理解的人並不多,很多時候都是人云亦云。=========

連載面向物件葵花思想技巧實踐27

類模型指導我們如何宣告類,動態模型指導我們如何實現類!動態模型設計一般都是在類模型設計完成後才開始,因為動態模型設計的時候一般都需要用到類模型中的類。相對類模型來說,動態模型要相對簡單一些,主要原因在於

連載面向物件葵花思想技巧實踐18

很多人在分析需求的時候,採用的是東扯葫蘆西扯瓢的方式,列出了很多的需求點,但當你看完後,你還是不知道到底要幹嘛!!  ---- 寫在前面用例,英文名稱Use Case,英文和中文都是很好理解,因為大家都

連載面向物件葵花思想技巧實踐19

完成了用例之後,需求分析的工作基本上已經完成,接下來我們需要趁熱打鐵,完成另外一個事情:提取功能點!有了用例之後,提取功能可以說是一個水到渠成的事情,基本上只是一個文字工作,我們只需要將用例中那些需要系

華仔-技術部落格面向物件葵花》,寫程式碼的架構師,做技術的管理者

面向物件葵花寶典 面向物件葵花寶典,主要從理論、實踐、技巧3個方面獨樹一幟的闡述了面向物件相關的知識和技能。教你如何從需求開始,一步一步、環環相扣的走到編碼階段,理論闡述別具一格,實戰技巧簡單好用,是面向物件快速入門和提升的”葵花

IDEAL葵花java代碼開發規範插件 FindBugs-IDEA

finall rem width find 是否為空 col cnblogs input -s 前言:   檢測代碼中可能的bug及不規範的位置,檢測的模式相比p3c更多,寫完代碼後檢測下 避免低級bug,強烈建議用一下,一不小心就發現很多老代碼的bug。 使用步驟: 1

IDEAL葵花java代碼開發規範插件 lombok 插件

其中 wid alt www. 新建 實習 oar idt null 前言: lombok簡介:   lombok是暑假來到公司實習的時候發現的一個非常好用的小工具,剛見到的時候就感覺非常驚艷,有一種相見恨晚的感覺,用了一段時間之後感覺的確挺不錯,所以特此來推薦一下。   

IDEAL葵花java代碼開發規範插件 Rainbow Brackets 插件

height image ima 推薦 若有 大括號 ack line inf 前言:   最近在Jetbrains IDEA插件網站逛發現了 Rainbow Brackets這款插件,非常棒,推薦給大家。   可以實現配對括號相同顏色,並且實現選中區域代碼高亮的功能。  

IDEAL葵花java程式碼開發規範外掛 FindBugs-IDEA

 前言: 檢測程式碼中可能的bug及不規範的位置,檢測的模式相比p3c更多,寫完程式碼後檢測下 避免低階bug,強烈建議用一下,一不小心就發現很多老程式碼的bug。 使用步驟: 1):開啟 Settings---->Plugins---> 進行搜尋--->選擇---->"FindBug

IDEAL葵花java程式碼開發規範外掛 checkstylevisualVMPMD 外掛

前言: visualVM: 執行java程式的時候啟動visualvm,方便檢視jvm的情況 比如堆記憶體大小的分配;某個物件佔用了多大的記憶體,jvm調優必備工具。 checkstyle: CheckStyle是SourceForge下的一個專案,提供了一個幫助JAVA開發人員遵守某些編碼規範的工具。   

路徑描述語言摘自《葵花WPF自學手冊》李響

(P407)路徑描述語言的所有命令: 命令 含義 PathGeometry和PathFigure屬性 Fn    設定填充規則(FillRule),其中0表示EvenOdd; 1表示NonZero,該命令在所有字串之前。 Mx,y          開始一個新的PathFi

JVM高級特性實踐對象存活判定算法引用 回收

添加 引用計數器 程序計數器 正文 bmc 進入 block 結構 內存 關於垃圾回收器GC(Garbage Collection),多數人意味它是Java語言的伴生產物。事實上,GC的歷史遠比Java悠遠,於1960年誕生在MIT的Lisp是第一門真正使用內存動態分配和垃

第二篇基於深度學習的人臉特徵點檢測 - 資料方法轉載

https://yinguobing.com/facial-landmark-localization-by-deep-learning-data-and-algorithm/ 在上一篇博文中,我們瞭解了人臉檢測與面部特徵點檢測的背景,並提到了當前技術方案存在特徵點位置不穩定的缺點,需要新的解決

Webpack原理實踐打包流程

寫在前面的話 在閱讀 webpack4.x 原始碼的過程中,參考了《深入淺出webpack》一書和眾多大神的文章,結合自己的一點體會,總結如下。 總述 webpack 就像一條生產線,要經過一系列處理流程後才能將原始檔轉換成輸出結果。 這條生產線上的每個處理流程的職責都是單一的,多個流程之間有存在依賴關

python3入門實踐函數語言程式設計

匿名函式 lambda # 1.parameter_list 引數列表 # 2.expression 函式體,只能是有一些簡單的,注意不是程式碼塊,比如不能寫賦值語句 # 3.不需要return lambda parameter_list: expression 複製程式碼 def add(x,y):

字典 set什麼是字典及如何訪問新增修改刪除字典中的值

(一)、什麼是字典 字典:字典是放在花括號中一系列的鍵-值表示 # This is a dict student_0 = {'name': 'zhangsan', 'age': '20'} 冒號