#學習筆記Design Pattern part.0 OOP

Jia
9 min readSep 6, 2020

2020.09.06 碼農邁向設計師,物件導向(OOP)

前言:昨天再學習關於Design Patten,基礎的物件導向設計我卻不是很熟悉,因為一開始是從JavaScript 入門,在ES5中,並沒有Class類別,所以這塊在接觸C#後才慢慢認識,現在想想當初若還沒寫程式就開始學習這個,應該早經死在前面的學習陡坡了XD,所以這篇來回顧複習甚麼是物件導向。

這篇依舊是水球潘 大大 與小山大大的影片筆記,影片連結會貼在下方!

保哥對於OOP基礎概念也很完整與清楚,有興趣的也可以去看看。

在開發專案時,通常在一個專案的週期,開發與維護兩個所占時數,維護經常會佔比較多數,因此程式的可讀性擴充性就相當重要而要讓程式具備此兩項特性,OOP的概念與寫法就是解決方案。

在進入物件導向程式(Object-oriented programming)介紹前,必須先提及其他導向,分別為:

>功能式導向程式(functional programming)

功能式導向程式 :比如一開始設計一個系統,就將所有方法寫完。如一個抽鬼牌的遊戲,一開始就將所有功能寫完,。如一個抽鬼牌的遊戲,一開始就將所有功能寫完,但若隔一個禮拜要寫一個大老二的遊戲,功能的重複利用姓大概不超過80%,這是問題所在。

>資料導向程式

資料導向程式:比如XML格式,或是程式一開式宣告類別的屬性或欄位public string GetPeople{   string name="Peter";
return name
}

而物件導向則是融合功能式導向程式資料導向程式的特點。

名詞解釋

  1. 類別與物件(Class&Object)
甚麼是類別(Class)?Peter:阿就是,比如阿,你在寫C#時,不是有很多種資料型態,比如說string 字串,int 整數,有時候開發的時候,你想自己設計一種資料型態,比較複雜一點的,你就會用到class 啦,比如你做一個學生管理系統,這個系統有十幾個頁面,每個頁面都需要學生的資料,所以你就會這樣設計...
class Student{
public string name{get;set;}//姓名
public string gender{get;set;}//性別
public string years{get;set;}//年紀
}因此一個class 就是一個資料型態,
你宣告一個string 是如此,所有class 就像是一個設計藍圖,上面的就是學生資料的設計藍圖
string A = "AA";
宣告一個class 就是如此
Student Peter = new Stusent();//所以啦,Class(上面的Student) 就是物件型態,而變數就是Object(上面的Peter);
//上面的 把它new 出來,就是所謂的 實例化(instantiate)

2.抽象

真實世界的需求轉換成為OOP中的類別,

類別可包含狀態(屬性)與行為(方法)。

就像是你要製作一個客戶的買賣系統,你可能就會定義一個這樣的客戶模型....class Custome
{
private string Name;//定義客戶名字屬性
private string Gender;//定義客戶性別屬性
private int Index;//定義客戶專屬ID屬性
public string SayName()//定義客戶方法
{
return this.Name;
}}

3.封裝( Encapsulation)

隱藏/保護內部時做細節,並可以對屬性或方法設定存取層級

封裝就是,將相關的功能、參數、全部包成同一個物件,並有private,的修飾字,可以讓相關功能參數能不暴露出來,不讓使用此物件的人隨意修改或存取。比如內在參數,不讓人隨意直接用. (存取)修改參數,這樣方法不建議的,應該將存取方式寫出來(自己寫的方法),基於擴充性與維護性。就是所謂的Getter SetterPS:關鍵字
public:任何人都可以隨意使用,比如調用方法就能進行修改。
private:只有自己能觀看、使用及修改,就算是兒子(繼承類)也不行。比如調用方法就不能進行調用,只能在class 裡使用。
protected:只有自己的衍生類可以使用。
(繼承的也不能使用private 所指定的變數與方法。
解決的方法就是protectrd 修飾字)

4.繼承(Inheritance)

可以讓其他物件繼承該物件的屬性方法,視為繼承。讓物件重複利用,降低程式碼的複雜程度。

假如有天你要設計一款RPG遊戲,遊戲裡有三種腳色,分別為 村民勇者怪物,但這三種腳色都是生物,因此先設計一種生物的類別,作為基底類。class Create
{
//基本屬性
private int mp;//魔力
privateint hp;//生命
private int Name;//腳色的名字
//共同方法 public string getHp(){//取得hp的方法 return this.hp;
}
public string Attack( Create target){
///
攻擊的方法,!!參數放Create這個基類,所以代表村名、勇者、怪物這三種衍生類都能傳進來。
///
return target.Name +"被"+ this.Name+"攻擊了";
}
}

有了生物後,可以來創造村民勇者怪物 啦

class Vallage:Create//繼承Create)
{
//屬性方法會自動繼承。
}

在此例子中,Create就是所謂的基類,或叫父類,而村民就是所謂的子類,或衍生類。

而在衍生類別撰寫中,可以用base關鍵字呼叫基類,相對於this是代表衍生類本身。

5.多型(Polymorphism)

在相同的介面下,可以用不同的類別來實作,而多型有分好幾種不同的類型。

在介紹多行前,要先介紹一下Override,(覆寫,改寫)?

開發到一半,你突然覺得,一般來說,你玩RPG時,村民這種NPC應該是不能攻擊的吧,如果直接讓村民繼承 Create,那村民就有攻擊這種方法了,好像不太好,所以,這時就要運用 Override(覆寫,改寫)來修改村民的攻擊方法,讓他不能攻擊。

而如何撰寫呢,主要分為兩步驟

1.在父類別要改寫的方法 加上virtual 關鍵字2.在子類別再寫一次方法,在繼承類別要改寫的方法先在寫一次,加上override關鍵字 並自己從新設計。

所以,那個多型到底是啥?好吧,其實我還是很不明白(被揍)。

要理解抽象很難,因為沒有實體,所以只能透過聽來理解在心中產生具體的形象。就如同人生第一次遇見狗狗,你能透過看到狗的樣子,聽到狗的叫聲,聞到狗的味道,摸到狗的感覺,利用這些不止一項的單一知識,來構建心中對於狗的具體認知,所以要理解一個很抽象的概念,可以聽聽不同人對於抽象概念的想法

所以讓我們先來網路上的各個大大對於多型的一些說法

1.利用統一的介面存取物件,提高使用物件的彈性

2.不同型態的物件,定義相同的操作介面,由於被呼叫者 (Callee) 有著相同的介面,呼叫者並不用指定特別型別,只需針對介面進行操作。

3.子類別的物件宣告或轉型成父類別祖先類別 的型別時,還可以正確執行該子類別的行為。

4.字面上的意思是一個東西有很多型態,但在物件導向的程式設計法中,多型也可說是「一個介面,數個功能」

可以看到其中介面似乎是關鍵,因為幾乎都有提及,

其實多型在上面已經有講到了,就是 程式碼 public string Attack的部分,我們依賴最底層的Create ,這樣我們就不必去了解衍生類,依賴統一的介面(Create)。

而介面(Interface)這個的概念,就像是你有兩種基類,分別為貓貓和狗狗,他們是不同的類,但都有呼吸和吃飯的方法,都有血量年齡的屬性,當兩個類別要共用一個方法屬性,定義這種橫跨類別的動作及屬性便是介面(Interface),將不同類,卻是共同的方法拉出來做。

所以狗狗會吃,貓貓會吃,都有吃的這個介面。但平平的是吃,卻有不同的吃的方法,這就是多型

再來事也是很重要的物件導向設計(SOLID),

物件導向設計(SOLID)

依循SOLID原則,可以寫出比較好的程式碼。

依循SOLID原則,能夠判斷程式碼的好壞。~保哥

S:單一職責原則(Single responsibility principle, SRP)
每一個物件方法應當只做一件事就好。

A Class shoud have one reason to change.
一個類別應該只有一個改變的理由

O:開放封閉原則(Open-Close Priciple,OCP)

當功能變改時,該藉由增加新的程式碼來擴充系統的功能。避免修改原本的程式碼來擴充系統的功能。
(Peter:當工程師的這段日子,接觸到維護案,有著能不改寫原本Code就不改寫的心態,只添加新的程式碼達到需求而非修改XD)

L:里氏替換原則(Liskov substitution principle, LSP)

如果你有一個類別(Class)實作(implements) 了一個介面(interface),那任何使用這個介面的地方,底下的實作類別應該可以被抽換成另一個有實作該介面的類別,而不需要修改原本的程式就能正常運作,這也同時符合OCP原則,因此你違反了LSP,通常表示也違反了OCP,這會讓你的程式碼很難維護,容易改東錯西。只要是繼承父類別的物件。在程式中,只要出現父類別物件的部份,都可以用子類別替換。

I:介面隔離原則(Interface segregation principle, ISP)

針對不同需求的用戶,開放其對應需求的介面,提供使用。可避免不相關的需求介面異動,造成被強迫一同面對異動的情況。

D:依賴反轉原則(Dependency inversion principle, DIP)

類別中,不應該直接使用另一個具有實作類別,而是使用抽象的介面,去承接繼承該介面的實作類別。它的目標就是解除物件與物件間,兩者的直接相依關係。

(Peter:就是阿,物件與物件間不要直接相關,而是透過介面去連結,有點像MVC裡,不讓View直接去和Model 溝通是一個道理)

參考資料:

Java物件導向 重觀念迅速教學 (1) Class and Object ; Abstraction 什麼是OOP ? 為何使用OOP?

Java物件導向 重觀念迅速教學 (2) 封裝 Encapsulation 到底為何封裝? 為何使用Getter和Setter?

小山的 C# 教學-第28課-繼承性

小山的 C# 教學-第47課-多型性 (Polymorphism)

20. 自動化測試 — 觀念篇

.NET 技術講座:打造堅固耐用的 C# 程式碼

--

--

Jia

看一次不懂 就看兩次吧。每一天努力一點,不知不覺就會成為想像中的樣子的。 like60955@gmail.com