>[success]
> **所謂的抽象,就是將一系列事物共有的特質提取出來,舍去獨有的部分的過程**
> **也可以說是指從具體問題中,提取出具有共性的模式,再使用通用的解決方法加以處理**
## 通俗的理解抽象
大家從小到大學到的大部分知識,無一例外的都是將具體事物抽象出來的結果
例如大家學到的 1+1 = 2 這個概念,如何理解和抽象的關系?
一只雞加一只雞等于兩只雞,一只狗加一只狗就是兩只狗
**這個過程中,共有的特質就是一個實體加另一個實體,就等于了兩個實體,獨有特質就是一個是貓,一個是狗。**
于是加法了概念就這樣誕生,在你理解了這個概念后,就可以靈活應用,比如你就會知道一個人加一個人就等于兩個人
而學習知識最好的辦法就是將抽象的知識類比為具體的事物來學習,比如老師教你們1+1 = 2 這個概念,是不是就是舉的例子,一只雞加一只雞等于兩只雞這樣?
**而我們在應用學習到的知識時候,也是這個道理,先將具體問題抽象為我們所儲備的知識,再用知識去解決問題**
一個車可以座5人,10個車能做幾人?我們要解決這個問題,得先把問題轉為我們學過的數學乘法,在計算出結果
## 抽象和編程的關系
看到這里你應該對抽象有了一定的理解,那么抽象和編程有什么關系?
>[success]
> 一個軟件的架構寫的如何,包括拓展性,可維護性,可移植性等等方面幾乎直接由程序開發者對事物的抽象能力來決定,他們能根據項目的需要總結出什么地方需要用什么算法,什么數據結構,什么設計模式等等。
> 大家所熟知的各類設計模式,數據結構,算法,就是對各種情況抽象出來的結果。
所以各位應該知道為什么學習這些知識如此重要。
>[success]
>
> Thinkphp框架的源碼就是不錯的典范,不少朋友說是仿的 laravel,這里拋開框架整體思想不說,僅討論代碼的規范和各種設計思想,十分是值得大家學習
**為什么要抽象**
> 代碼可復用性強,表現為同樣的功能,絕不寫第二次,沒有重復功能的代碼 參考 Thinkphp源碼里 `think\File `類的 `getInfo `方法,寫好后其他地方只管調用即可
> 代碼可移植性強,寫好的功能可以把代碼提出來拿到其他項目里用,沒有耦合(關于耦合的概念看文檔的‘耦合于解耦’篇)參考Thinkphp源碼里的` vender\topthink\think-image`能,使用composer安裝,即便拿到其他框架一樣可以工作,不會依賴 Thinkphp源碼里的任何類庫或者函數
**抽象的原則及如何抽象**
抽象需要對計算過程進行觀察,看哪些計算模式是固定的,哪些是經常變化的,將共有的部分提取出來封裝。
> 通常在抽象時需要遵循一個‘**三次原則**’
通俗的說,在編寫項目過程中,當一個重復的功能出現在三次以上的地方時候,就應該考慮將共有的部分封裝為函數或者類,在需要用到的地方調用,不同的部分用傳參數的方式傳進去
> 第一次用到某個功能時,你寫一個特定的解決方法;
> 第二次又用到的時候,你拷貝上一次的代碼;
> 第三次出現的時候,你才著手"抽象化",寫出通用的解決方法。
### 理由
> (1)省事。如果一種功能只有一到兩個地方會用到,就不需要在"抽象化"上面耗費時間了。
> (2)容易發現模式。"抽象化"需要找到問題的模式,問題出現的場合越多,就越容易看出模式,從而可以更準確地"抽象化"。
> (3)防止過度冗余。如果一種功能同時有多個實現,管理起來非常麻煩,修改的時候需要修改多處。在實際工作中,重復實現最多可以容忍出現一次,再多就無法接受了。
>[warning]
> 當然,面對一些能預知的通用功能,應該先封裝好,在進行封裝,后面在調用,比如類似排序函數之類的功能等
**通常封裝的形式粒度由小到大**
> 1. **函數和類中的方法** : 參考thinkphp源碼里 `helper.php` 里的函數
> 2. **類** : 包括工具類,機制類等等,參考thinkphp源碼里 thinkphp 命名空間下的各個類文件,session,url等等
> 3. **類庫** : 功能比較龐大,一個類封裝不了的時候,可以考慮封裝為多個類,各司其職,相互調用完成復雜邏輯,類似phpexcel,phpMail這樣大型工具庫,可以參考thinkphp源碼里` think\cache` 文件夾下的各個類
>[success]
> 經驗豐富的程序設計者,總是可以判斷出做出什么程度的抽象是合適的
**面向對象中的抽象類 abstract**
如何理解面向對象中的抽象類(abstract)
參考thinkphp源碼里` think\cache` 文件夾下的各個類文件
你會發現有個Driver.php里面有個`abstract class Driver`,有好幾個方法如` has,get,set`等都是沒有方法體,前面用了 `abstract`修飾。再看`driver`文件夾下有很多文件,這些類文件繼承了`Driver`,他們每個類都重寫了`Driver`類里的用`abstract`修飾過的方法,在這里就是對緩存這個動作做了抽象的結果。
>[success]
> **共有特質**:不論用何種方式緩存,`File,Memcache,Redis`等等,必然都有個`set,get,clear`等一些方法
> **獨有特質**:每個方式寫入數據的方式都不一樣,參考每個繼承了`Driver`的類,如`File,Memcache`等,他們重寫的方法體里就是具體的邏輯
>
>[success]
> **另外,這個設計思想是典型的適配器模式
> 同樣的示例參考 `namespace think\db\connector` 下各個類文件和 `namespace think\db `下的`Connection`類之間的關系**
- 序言
- 圖片預覽
- 詮釋高效開發
- 提問的智慧
- GIT命令參考
- 安裝composer
- 斷點調試技巧
- 調試環境的搭建
- 調試工具的使用及技巧
- 前置基礎-TP底層講解
- 理解編程的抽象
- 耦合與解耦
- 自動加載
- 反射類
- 控制反轉(IOC)和依賴注入(DI)
- iThink 自定義依賴注入的實現
- 常用設計模式
- SPL標準庫
- 行為-鉤子-插件
- AOP-面向切面
- RBAC和Auth類的本質
- 安裝iThink
- 環境要求
- 代碼下載與環境配置
- 執行安裝
- 體驗測試模塊
- apache配置
- nginx配置
- 系統架構詳解
- 目錄詳解
- 執行流程圖
- 數據字典
- RBAC 權限管理架構
- 系統分層詳解
- 控制器層(controller)
- 邏輯層(logic)
- 視圖層(view)
- 模型層(model)
- 服務層(service)
- 應用包架構詳解
- 目錄結構
- 開發規范
- 數據庫規范
- 編碼規范
- 功能設計原則與規范
- 后臺功能詳解
- 基礎功能
- RBAC + Auth 權限機制
- 應用化功能機制
- 代碼生成器(重要)
- 應用骨架代碼生成
- 數據表 CURD 代碼生成
- 頁面構造器(重要)
- 通用元素構造器
- 表格元素構造器
- 搜索表單元素構造器
- 表單元素構造
- 閉包事物構造器
- 應用的開發
- 函數參考