---
# System prepended metadata

title: 程式設計範式與OOP的思考術：冒號老師的十三堂課 - 上篇：程式設計範式與程式語言
tags: [薛威明, 讀書會]

---

![image](https://hackmd.io/_uploads/HklIGL13C.jpg)

[影片](https://youtu.be/ZEyT9wtXN0Q)
[下篇：抽象機制與物件範式](https://hackmd.io/vdNw4pp3QqGVWznW80c-rg)
[博客來](https://www.books.com.tw/products/0010687596)

2008 網頁
2015 二版
## 函式庫、工具包 vs 框架
* 函式庫、工具包：程式碼複用，讓工程師不用從底層打造，帶來自由
* 框架：設計的複用，控制整體結構和流程，帶來限制。控制反轉(IoC)

## 設計模式 vs 架構
* 設計模式：戰術思想
* 架構：戰略決策 (MVC、MPV...)

## 設計模式 vs 慣用法(Idiom)
* 針對常發生問題提供解決方案。前者偏重設計；後者偏重實作

## 補充
* ASP、JSP：用於靜態網頁植入能在伺服器運行的程式，因為不涉及新的語言，故稱為模板、框架或腳本環境更合適。PHP則屬於新的程式語言，除了用於伺服器，還能編寫命令列腳本和桌面應用程式

# 範式
設計範式 Programming Paradigm
風格或典範
常用Oriented表述，某種傾向
## 1. 命令範式
* 結構化：循序、選擇、迴圈(while、util) - 只用這幾種才是標準的
* 單入口、單出口 = SESE = Single Entry Single Exit
* 善於互動式或事件驅動，使用者導向
* 提倡迭代不鼓勵遞迴
	* 一般效能開銷較大
	* 除了尾歸遞迴Tail Recursion
		* 因為編譯器能把尾歸轉成迭代
		* 
## 2. 宣告範式
* 數學思維 x=6 定值
	1. 函數式：宣告定義
		* 閉包：創建匿名類別，記住外部類別的局部變數
			包：環境變數綑綁打包
			閉：變數是封閉，指給該函數使用
	2. 邏輯式：表達邏輯
	vs 命令式=提供演算法 i=i+1 定址，模擬電腦
* 後兩代語言基本上都是宣告式，模擬人腦
* 善於數理邏輯應用
* C# attribute就屬於宣告式應用
* 不支援迭代
	 
| 範式 | 程式 | 輸入 | 輸出 | 程式設計 | 程式運行 |
| - | - | - | - | - | - |
| 命令式 | 自動機 | 初始狀態 | 最終狀態 | 設計指令 | 執行命令 |
| 函數式 | 數學函式 | 自變數 | 應變數 | 設計函數 | 運算式變換 |
| 邏輯式 | 邏輯證明 | 假設 | 結論 | 設計命題 | 邏輯推理 |

![螢幕擷取畫面 2024-03-13 094947](https://hackmd.io/_uploads/ry5v8K06a.png)

## 3. 物件範式
* 貼近真實世界的物質
* OOP是物件+繼承、多形
	* 封裝使得物件擁有個體身份
	* 繼承使得物件擁有家庭身份
	* 多型使得物件擁有社會身份
* vs 程序式
	* 物件式：資料為中心，自底向上，逐步合併 (民主制)
	* 程序式：程序為中心，自頂向下，逐步求精 (君主制)
	> 對一個沒有獨立思考習慣的人來講，與其說他認同一個理論，
	> 倒不如說他認同該理論宣導者的權威。
	> 而在他仰視權威的同時，也把自己的思想交託給了權威。
	
## 4. 並行範式
* 貼近真實世界的互動
* vs 串列式
* 基本單位：程序(Process)及執行緒(Thread)
* Precess-Oriented
* 生產體系：資源在各模組競爭與合作

## 5. 泛型函式  (演算法導向)
* C++ template、C #define、C# <>
* 打破靜態語言資料之間的壁壘
* 不犧牲效率又確保安全，提高演算法普遍性
* STL三要素
	1. 演算法
	2. 容器
	3. 迭代器：演算法與容器之間的介面，抽象化的指標(因此行為也能被泛化)
	> 1. 從一個整數陣列中隨機抽取十個數，對其中的素數求和
	> 2. 將一個無序整數集中所有的完全平方數換成其平方根
	> 3. 從成績表中，列出所各科及格且平均分數70以上的學生名單
	> 4. 再一個著色二元樹中，將所有紅色節點塗成藍色
	> 5. 將一個字串從倒數第三個字元開始反向拷貝到另一個字串中
	> 6. 每從標準輸入讀取到一個非數字的字元X，於標準輸出列印出「X不是數字字元」
	```c++
	template< class Iterator , class Act , class Test >
	void process( Iterator begin , Iterator end , Act act , Test test )
	{
		for( ; begin != end ; ++begin )
			if( test( *begin ) ) act( *begin );
	}
	```
	```c++
	#include <iostream>
	#include "prcess.h"

	using namespace std ;

	bool notDigit( char c )
	{ return ( c < '0' ) || ( c > '9' ); }

	void printNodDigit( char c )
	{ cout << c << "不是數字字元" << endl ; }

	int main()
	{
		process( istream_iterator< char >( cin ) , istream_iterator< char >() , printNonDigit , notDigit );
		return 0 ;
	}
	```

## 6. 超級範式 (元程式Metaprogramming：寫程式的程式)
* 編寫操作程式的程式。傳統運算是動態，程式本身靜態；在元程式，兩者皆是動態
* 自編的元程式
	* ~解碼器
	* 可使資料簡化，隨時修改(自定義資料格式)
	* 程式當作資料對待
*  eq 編譯器：高階->組合
* ->語言導向程式設計(Language-Oriented Programming = LOP)。專用語言->通用語言
* -> 生程式程式設計(Generative Programming)

## 7. 切面泛式 Aspect of point = AOP
* Soc = Separation of Concerns 關注點分離
	將結構混亂或是疊床架屋的程式碼抽象出關注議題，以此分解程式碼
* 切面為模組，橫切關注點(Cross-Cutting Concerns)
	* 主流執行方向為縱向(OOP繼承、執行順序)
	* 有些程式碼卻跨模組，難以實現Soc和DRY
* 接入點(Joint Point)：執行處
* 切入點(Pointcut)：符合執行的接入點集合
* 建議(Advice)：被連結的程式碼
* 織入(Weaving)：程式若是管道，AOP就是在管道上鑽孔，注入新的程式碼。分靜態和動態注入
* 如同三稜鏡：
	1. 切面分解：設計者構思
	2. 切面實作：程式設計師實作
	3. 合成切面：AOP工具負責
* 額外效能開發，用於大中型的程式

## 8. 事件驅動 Event-Driven Programming = EDP
* vs 流程驅動式程式設計 Flow-Driven Programming
* 控制反轉：主從地位反轉
	* 提供框架，其他類別填空
* 依賴反轉：解偶上下層
* Callback：底層可以呼叫上層
* 觀察者模式可看作簡化版的事件驅動
	* 省略了管理器部分
		* 事件：轉化、合併、排隊、分派
		
![SKMBT_C36024072209580-1](https://hackmd.io/_uploads/HJeciridA.png)

# 語言

## 五代語言
1. 機器語言
2. 組合語言
3. 高階語言：C常會被說中階語言，介於高階與前兩代語言
4. 問題導向語言：專門領域設計，但不再廣泛領域應用
5. 人工自智慧語言：能更口語開發廣泛設計

## 系統語言
### C++ 
* 反射功能不足 -> 為了效能
* 完全支援指標導致安全隱患 -> 底層所需
* 沒有GC (軟肋一：擔心造成過大的時空開銷)
	* 替代方案RAII(Resource Acquisition Is Initialization) -> Smart Pointer
		* 資源獲取及初始化
		* RRIF (Resource Release Is Finalization)
			* 資源釋放即終結化
* 沒有執行緒
* 沒有豐富標準函式庫 (軟肋二：僅有效率極低的標準委員會維護，缺乏大公司鼎力資助，D語言更慘)

## 平台語言(Java & C#)
* 編譯生成與機器無關的受控碼(Managed Code)或位元組碼(Bytecode)
* 執行於VM上
* '.' 機器性能、軟體規模過大 -> GC的方便
	* b. 效能仍是需要重視的議題
* 禁用指標 -> 類型安全

### Java 
* = C++++-- (c++加加減減)
* 一種語言跨平台(語言擴散)
	* JVM (Java Virtual Machine)

### C# 
* = 音符裡的高半音符號 != C四個加
* 多種語言在一種平台上.net執行(凝聚語言)
	* CLR (Common Language Runtime)
* unsafe -> 指標操作
* Delegate、event
	* 閉包、Lambda(函數式)
* checked、yield
* 匿名類型

## 前台語言

* 視覺化開發 (B/S架構 vs C/S架構)
* 效率要求低

### VB

* 前身BASIC (Beginner's All-Puppose Symbolic Instruction Code)
* 學習曲線短

### Delphi

* = Object Pascal。前身Pascal(教學語言)
* 不限於Window

### JavaScrip (動態語言。eq: Perl、PHP、Python、Ruby)

* X Java
* 可用於伺服器(SSJS)
* 配合HTML、CSS、XML和XSLT才能完成前台工作
* 基於原型的OOP (用現有的物件去擴充，而非定義類別來實現)
* 標準、普及
* 瀏覽器標準不統一、除錯工具不理想

## 後台語言
* Perl 強大複雜
* Python 簡單易學 效率差
* Ruby Perl + Python
	* 執行緒件在使用者空間而非內核空間 (X充分利用多核)
* PHP 相較下過於簡單，但流行
* 動態語言->網路平台
	* LAMP (Linux Apache MySQL PHP或動態語言)

## 資料類型
* 要素：
	1. 值的集合
	2. 允許的運算
* 意義：
	* 機器物理意義：底層記憶體配置和數值運算
	* 人邏輯意義：表達高層邏輯概念

### 類型檢查發生期間

1. 動態類型語言
	* 執行期間
	* != 動態語言
	* 鴨子類型 (Duck Typing)
		* 鴨&蛙：叫&游
			* 動O靜X  ShoutAndSwim( _animal )
		* 雞&魚：前叫後游
			* 動O靜X ShoutOrSwim( _animal )
		* C++靜態語言類型
			* B. 範本可實現And的類似功能，但Or無法
		* 非繼承多型
2. 靜態類型語言
	* 編譯期間

### 值轉換類型

1. 弱類型語言
	* 允許隱性轉換
		* 1 + "2"
			* VB = 3
			* JavaScript = 12
			* c = 記憶位置偏移
2. 強類型語言
	* 貫徹類型控制
		* 鑄型Cast

### 安全性
1. 類型安全語言
2. 類型不安全語言

## 動態語言

* 目前動態語言沒有明確定義
* ~腳本語言
	* A script is what you give the actor, a program is what you give the audience
	* 字元導向
		* 靜態語言數值導向。依賴函式庫
	* 常見形式：
		1. Shell script 介殼腳本
		2. Batch File 批次檔案
* 膠水語言 (Glue)
	* 用於系統管理及集成
	* 不同語言之間結合

[下篇：抽象機制與物件範式](https://hackmd.io/vdNw4pp3QqGVWznW80c-rg)