面向對象的設計過程

前言

我一直認爲分享的目的不是炫技。數據庫

  • 一是,自我學習的總結。
  • 二是,下降他人的學習成本。
  • 三是,別人對本身學習結果的審覈。

同時,本次分享有下面四個要素:編程

觀點 本次分享的觀點是一個軟件工程中的思惟方法,不限於編程語言
探討 我可能理解錯的,或者你們沒理解的,歡迎你們積極評論,儘量多互動,目的增長理解
理解 真的但願你們能理解
運用 最重要的,若是你覺着有幫助,必定要去在實際業務中實戰

背景

工做中,幾乎你們常常抱怨別人寫的代碼:設計模式

  • 無法改
  • 耦合高
  • 沒法擴展

今天就來探討如何克服上面的問題~緩存

場景

首先問個問題:bash

日常工做中來了一個業務需求,咱們是如何開始寫代碼的?閉包

我推測大多數人可能:架構

  • 一、梳理業務
  • 二、設計數據庫、接口、緩存
  • 三、評審
  • 四、因而就開始了 怎麼怎麼樣...若是怎麼怎麼樣...怎麼怎麼樣...愉快的碼代碼的過程

此處有人覺着有啥問題麼?編程語言

備註:說出來問題的,本次分享就能夠略過了~
複製代碼

一個簡單的業務場景

好比產品提了個需求:
描述「我一個同事」一天的生活,簡單來看看他一天干些啥:

1.0 餓了吃飯
1.1 到點吃飯

2.0 渴了喝水
2.1 到點喝水

3.0 困了睡覺
3.1 到點睡覺
3.2 有可能一我的睡覺,也有可能... 是吧?複雜
複製代碼

剛開始,一個業務邏輯從頭寫到尾函數

一個業務邏輯(拆成多個函數)從頭寫到尾:學習

一個業務邏輯(引入類)從頭寫到尾:

一個業務邏輯(拆成多個類方法)從頭寫到尾,也許、可能、貌似、猜想大多數人停留到了這個階段。 問題:某一天多了社交的能力,咋辦?

一個業務邏輯(拆成多類)從頭寫到尾:

一個業務邏輯(拆成類、抽象類、接口)從頭寫到尾:

思考🤔:上面的代碼就沒啥問題了嗎?

上面就是面向對象設計的代碼結果。

因此,如何設計出徹底面向對象的代碼?

代碼建模

什麼是代碼建模?

把業務抽象成事物(類class、抽象類abstact class)和行爲(接口interface)的過程。

實慄🌰分析

又來看一個實際的業務場景:

最近「我一個同事」開始創業了,剛創立了一家電商公司,B2C,自營書籍《3分鐘學會交際》。最近開始寫提交訂單的代碼。

⚠️注意場景 1.剛創業 2.簡單的單體應用 3.此處不探討架構
複製代碼

通常來講,咱們根據業務需求一頓分析,開始定義接口API、設計數據庫、緩存、技術評審等就開始碼代碼了。

接口參數:
uid
address_id
coupon_id
.etc

業務邏輯:
參數校驗->
地址校驗->
其餘校驗->
寫訂單表->
寫訂單商品信息表->
寫日誌->
扣減商品庫存->
清理購物車->
扣減各類促銷優惠活動的庫存->
使用優惠券->
其餘營銷邏輯等等->
發送消息->
等等...
複製代碼

就開始寫代碼了怎麼怎麼樣...若是怎麼怎麼樣...怎麼怎麼樣...一蹴而就、思路清晰、邏輯清楚、很快搞定完代碼,很優秀是否是,值得鼓勵。

可是,上面的結果就是大概全部人都見過的連續上千行的代碼等等。上面的流程沒啥問題啊,那正確的作法是什麼了?就是接着要說的代碼建模

咱們根據上面的場景,開始建模。

業務分析少不了

一樣,首先,咱們看看提交訂單這個業務場景要作的事情:

換個角度看業務其實很簡單:根據用戶相關信息生成一個訂單。

  1. 梳理獲得業務邏輯
參數校驗->
地址校驗->
其餘校驗->
寫訂單表->
寫訂單商品信息表->
寫日誌->
扣減商品庫存->
清理購物車->
扣減各類促銷優惠活動的庫存->
使用優惠券->
其餘營銷邏輯等等->
發送消息->
等等...
複製代碼
  1. 梳理業務邏輯依賴信息
用戶信息
商品信息
地址信息
優惠券信息
等等...
複製代碼

再次迴歸概念

什麼是代碼建模?把業務抽象成事物(類class、抽象類abstact class)和行爲(接口interface)的過程。

獲取事物

好比咱們把訂單生成的過程能夠想象成機器人,一個生成訂單的訂單生成機器人,或者訂單生成機器啥的,這樣咱們就獲得了代碼建模過程當中的一個事物。

從而咱們就能夠把這個事物轉化成一個類(或結構體),或者抽象類。

獲取行爲

這些操做就是上面機器人要作的事情。

事物有了:訂單生成機器人 行爲呢?毫無疑問就是上面各類業務邏輯。把具體的行爲抽象成一個訂單建立行爲接口:

獲得UML

設計代碼

  1. 定義一個類

  1. 定義一個訂單建立行爲的接口

  1. 定義具體的不一樣訂單建立行爲類
參數校驗->
地址校驗->
其餘校驗->
寫訂單表->
寫訂單商品信息表->
寫日誌->
扣減商品庫存->
清理購物車->
扣減各類促銷優惠活動的庫存->
使用優惠券->
其餘營銷邏輯等等->
發送消息->
等等...
複製代碼

  1. 建立訂單

這裏的代碼該怎麼寫,這樣?

還能夠繼續優化嗎?

使用閉包。

PHP版完整代碼

Go版完整代碼

上面的代碼有什麼好處?

假如「我一個同事」又要新開發一個新的應用,新的應用建立訂單的時候又有新的邏輯,好比沒有優惠邏輯、新增了增長用戶積分的邏輯等等,複用上面的代碼,是否是就很簡單了。

因此如今,什麼是面向對象?

概念

面向對象的設計原則

  • 對接口編程而不是對實現編程
  • 優先使用對象組合而不是繼承
  • 抽象用於不一樣的事物,而接口用於事物的行爲

針對上面的概念,咱們再回頭開咱們上面的代碼

對接口編程而不是對實現編程

結果:RobotOrderCreate依賴了BehaviorOrderCreateInterface抽象接口
複製代碼

優先使用對象組合而不是繼承

結果:徹底沒有使用繼承,多個行爲不一樣場景組合使用
複製代碼

抽象用於不一樣的事物,而接口用於事物的行爲

結果:
1. 抽象了一個建立訂單的機器人 RobotOrderCreate
2. 機器人又有不一樣的建立行爲
3. 機器人的建立行爲最終依賴於BehaviorOrderCreateInterface接口
複製代碼

是否是完美契合,因此這就是「面向對象的設計過程」。

結論

代碼建模過程就是「面向對象的設計過程」的具體實現方式.

預習

設計模式

最後,設計模式又是什麼?

一樣,咱們下結合上面的場景和概念預習下設計模式。

設計模式的設計原則

開閉原則(Open Close Principle):對擴展開放,對修改封閉

看看上面的最終的代碼是否是完美契合。

依賴倒轉原則:對接口編程,依賴於抽象而不依賴於具體

結果:建立訂單的邏輯從依賴具體的業務轉變爲依賴於抽象接口BehaviorOrderCreateInterface
複製代碼

接口隔離原則:使用多個接口,而不是對一個接口編程,去依賴下降耦合

結果:上面的場景,咱們只簡單定義了訂單建立的接BehaviorOrderCreateInterface。因爲訂單建立過程可能出現異常回滾,咱們就須要再定義一個訂單建立回滾的接口
BehaviorOrderCreateRollBackInterface.
複製代碼

迪米特法則,又稱最少知道原則:減小內部依賴,儘量的獨立

結果:仍是上面那段代碼,咱們把RobotOrderCreate機器人依賴的行爲經過外部注入的方式使用。
複製代碼

合成複用原則:多個獨立的實體合成聚合,而不是使用繼承

結果:RobotOrderCreate依賴了多個實際的訂單建立行爲類。
複製代碼

里氏代換:超類(父類)出現的地方,派生類(子類)均可以出現

結果:很差意思,咱們徹底沒用繼承。(備註:繼承容易形成父類膨脹。)
複製代碼

下回預告

上面預習了設計模式的概念,下次咱們進行《設計模式業務實戰》。

相關文章
相關標籤/搜索