物件導向簡介

什麼是物件導向程式設計?為什麼要有物件導向?在 JavaScript 中實做的例子又有些什麼呢?

本篇就來簡單探討這些問題!

什麼是物件導向程式設計?

物件導向開發的英文是 OOP (Object oriented programming),初次聽到這個名字的時候,完全不知道是什麼,既不知道物件為何、又不知道導向是在導向什麼,唯一知道的只有 Programming。

所以要了解物件導向,就得從知道什麼是「物件」開始。

Class and Object

何謂物件(Object)?其定義是類別(Class)的實例(Instance)。又出現了兩個我初學時看不懂得名詞:Class and Instance。

所以在談物件前,先來看看所謂類別(Class)的定義,便是:一件事物的抽象特點

哇,好抽象的抽象定義呀!簡單來舉個例子,「人」是一個類別,我們可以為「人」加上一些資訊,像是有「名字」、「年齡」,並且可以「說話」。翻譯成程式碼就會像是

1
2
3
4
5
6
7
class Person {
String name;
int age;
public void talk() {
// Talk something
}
}

其中名字(name)和年齡(age)被稱做「屬性(attribute)」,而說話(talk)被稱做「方法(method)」。

Attribute 就是這個 Class 的一些資訊,而 Method 就是這個 Class 可以做的一些事情。在代入物件導向的概念前,其實 Attribute 就是 Variable(變數)、而 Method 就是 Function(函式)。

有了 Class 的概念後,就可以進入到 Instance 及 Object 為何了!

我們知道「人」是一種抽象的 Class,那我們要使用時怎麼辦?自然要把抽象的概念實體化,實體化的產物就是一個 Object,我們可以這個 Object 為 這個 Class 的 Instance。

例如 John 是一個人,我們可以用抽象的 Class 產生出一個 Instance,這就是叫做 John 的 Object。

1
Person john = new Person();

為什麼要有物件導向?

了解物件導向基礎的 Class 及 Object 後,我們來看看為何要這麼做呢?這麼做有什麼好處導致這個概念被發明出來?

根據 Wiki 的敘述,OOP 的雛形是在 1960 年代被就能被找到,而在 1980 年代逐漸成為一種主流。由於 OOP 之前的程式語言只有基本的變數、函式、條件判斷、迴圈等等概念,雖說已經可以重複利用程式碼,但在實做一些概念類似的功能時,單用 Function 無法做到太好的效果。

舉個例子來說,連接資料庫並實做一些操作這樣的事情,如果要連接兩個不同的資料庫,如 MySQL 或 PostgreSQL,我們可能可以寫一個 Function 叫做 connect,裡面傳入參數判斷是哪種資料庫:void connect(String dbType)

那實做讀取和寫入呢?類似 void read(String dbType)void write(String dbType) 的 Function 或許也行,但是我在讀取時是否要確認 connect 的是相同的資料庫,不然 connect MySQL 卻 read PostgreSQL,不就麻煩了?

這種錯誤可能不容易犯,但是當要傳入和暫存的資訊變多的話呢?情況就會變的更複雜一些了!

這時用上 OOP 的概念可以有效簡化這些問題,像是這樣的寫法:

1
2
3
4
Database mysql = new Database('localhost:3306');
Database postgresql = new Database('localhost:5432');
mysql.write('something');
postgresql.write('something');

是否感覺更清楚及容易閱讀一些呢?我們接著看看 OOP 有哪些特性!

物件導向三(四)大特性

  • Encapsulation 封裝
    簡單來說就是把一些資訊包起來,在使用 Instance 時你無法直接取得所有內容物,只能看公開的 Attribute 和使用公開的 Method。
  • Abstraction 抽象
    把現實世界的資訊轉換成一個 Class 的行為便是抽象(有些時候,這個特性不會被特別提到)
  • Inheritance 繼承
    Class 之下可以有 Subclass,而 Subclass 可以擁有 Parent Class 的 Attribute 及 Method
  • Polymorphism 多型
    當一個 Class 繼承另一個 Parent Class 時,此 Class 可以覆寫其 Method。如動物能生育,鳥和狗都是動物,但鳥的生育可以被實做成卵生,而狗則實做成胎生

物件導向五大原則 SOLID

  • S - Single Responsibility Principle 單一功能原則
    每個 Object 都只該有一個明確的功能,做到低耦合(Coupling)、高內聚(Cohesion)
  • O - Open Close Principle 開放封閉原則
    擴充時應新增程式碼(對此開發),而非修改現有程式碼(對此封閉)
  • L - Liskov Substituion Principle 里氏替換原則
    在替換 Subclass 時應該要可以保持程式的正確性
  • I - Interface Segregation Principle 介面隔離原則
    針對 Client 提出符合他們的 Inteface,改動程式碼時應讓他們可以使用原本的 Interface 而不至改變
  • D - Dependency Inversion Principle 依賴反轉原則
    Caller 和 Callee 應該由介面溝通,不至於 Callee 的 Code 改動會牽動到 Caller 也改

參考資料

  1. Wiki - 物件導向程式設計
  2. Wiki - SOLID
  3. 搞笑談軟工 - SOLID:五則皆變