--- tags: Pluralsight Note , Note For Object-Oriented Programming Fundamentals --- # Note For Object-Oriented Programming Fundamentals in C# ## Mur Mur 這個課程的講者好囉嗦. 連基礎語法都要介紹= = ## 前言 ![](https://github.com/s0920832252/C_Sharp/blob/master/Files/Note-For-Object-Oriented-Programming-Fundamentals/OOP_IS_Foundation.png?raw=true) **OOP 的概念是一切的基礎** 我們都希望寫出高品質易測試且未來不容易出錯的程式碼. 但這個目標應該如何達成呢 !? 為此有許多的理論(e.g. DDD or TDD)或是過去可供借鏡的經驗(e.g. 設計模式) 但這些比較高深的技術或理論都是基於 OOP 的概念再去做進一步的延伸. 以 OOP 三大特性為例 - 封裝 - 例如: - 關注點分離 - SRP 單一職責原則 - 繼承 - 例如: - 設計模式中的範本模式就是靠 OOP 繼承的特性去提供程式應對未來的變化. - LSP 里式替換原則 <-- 要求你正確地使用繼承 - 多型 - 例如: - OCP 開放封閉原則 <-- 若多個實體無法使用統一的符號替換, 則絕對不可能遵守 OCP - DIP 依賴注入 <-- 若多個實體無法使用統一的符號替換, 則 DIP 失去意義 ## 基礎名詞介紹 ### Static Modifier > the static Modifier declares a member that belongs to the class itself instead of to an object of the class. ### Method Signature > - a method's signature is its name and set of parameters. > - signature does not include the return type. > - the system use the signature to match the method call to the appropriate method ##### 參考資源 [Method Signatures in C#](https://www.c-sharpcorner.com/UploadFile/puranindia/method-signatures-in-C-Sharp) ### Overloading > Overloading describing methods that have same name, but different signatures - Since overloaded members have the same name they should provide variations of the same functionality ##### 參考資源 [C# | Method Overloading](https://www.geeksforgeeks.org/c-sharp-method-overloading/) ### Sealed class - Sealed class is a class that cannot be extended through Inheritance - use the word "sealed" to prevent overriding the class functionality (extension and customization) - A concrete class that can not be extended through inheritance ![AdvanSealedClasstagesReuse](https://github.com/s0920832252/C_Sharp/blob/master/Files/Note-For-Object-Oriented-Programming-Fundamentals/SealedClass.png?raw=true) #### Abstract vs Virtual - Abstract method is a placeholder, no implementation, that must be overridden - Virtual method is a method with a default implementation that can be overridden ![AbstractVirtual](https://github.com/s0920832252/C_Sharp/blob/master/Files/Note-For-Object-Oriented-Programming-Fundamentals/AbstractVirtual.png?raw=true) ### Abstract class - An incomplete class with one or more members that are not implememnted - An abstract class can not be instantiated - Intended for use as a base class ### Static Class - A class that cannot be instantiated - Access members using the class name ![StaticUse](https://github.com/s0920832252/C_Sharp/blob/master/Files/Note-For-Object-Oriented-Programming-Fundamentals/StaticUse.png?raw=true) - Use to organize utility methods - Members must also be static - Often used as a container for utility methods - It is Sealed - Defined with the static keyword ![StaticKeyWord](https://github.com/s0920832252/C_Sharp/blob/master/Files/Note-For-Object-Oriented-Programming-Fundamentals/StaticKeyWord.png?raw=true) - Use to organize utility methods ### Static Method vs Extension Method #### Static Method - Every method in a static class must be static - Define with the static keyword - Access a static member with the class name - Use static methods to create reusable utility methods #### Extension Method - Add Methods to an existing type without modifying the original type - Define by adding **this** to the first parameter ![ExtensionThis](https://github.com/s0920832252/C_Sharp/blob/master/Files/Note-For-Object-Oriented-Programming-Fundamentals/ExtensionThis.png?raw=true) - Great for adding methods to .Net Types - Extension methods appear in IntelliSense - Must be a static method in a static class - Access an extension method using the extended class instance ![ExtensionIUsingpng](https://github.com/s0920832252/C_Sharp/blob/master/Files/Note-For-Object-Oriented-Programming-Fundamentals/ExtensionIUsingpng.png?raw=true) ### Contract > All properties and methods defined using the public access modifier define the class contract. That is to say the class make a promise that it will provide a defined properties and methods to any other code in the application that need them. ![Contract](https://github.com/s0920832252/C_Sharp/blob/master/Files/Note-For-Object-Oriented-Programming-Fundamentals/Contract.png?raw=true) - Interfaces are a "Contract" - **Interfaces** - Define a role that an object can play - Define a contract - An interface is comprised of a list of properties, methods, events and iterators - Denoting the data and operations an object can perform - Specify the signatures of the interface members with no code - **Defining an Interface** - Add a new interface item to a project - Prefix the interface name with "I" - Specify the public access modifier - Add property, method, event, or indexer signatures - No need for an access modifier on the members - No Implementation of the members - Class Interface (Contract) - Every class has a basic interface - Defined by the public properties and methods of the class - The application uses this interface to work with the class in its primary role - 這裡的 Interface 指的是外界所能看到的資訊. ##### 參考資源 [Code Contracts in C#](https://www.infoq.com/articles/code-contracts-csharp/) ### Class vs Object vs Entity #### Class != Object - >**Class** is a user-defined blueprint or prototype from which objects are created. Basically, a class combines the fields and methods into a single unit >**Object** is an instance of a class that is created dynamically. Object is also a keyword that is an alias for the predefined type System.Object in the .NET framework. - ![Class!=Object](https://github.com/s0920832252/C_Sharp/blob/master/Files/Note-For-Object-Oriented-Programming-Fundamentals/ObjectVsClassCodeExample.png?raw=true) - ![Class vs Object](https://github.com/s0920832252/C_Sharp/blob/master/Files/Note-For-Object-Oriented-Programming-Fundamentals/ObjectVsClassExample.png?raw=true) - Class 像是做巧克力的模具 , Oject 則是使用模具做出來的實體(雖然是用同一個模具做出來的, 但每個實體之間可能有若干的不同.) - 冷知識補充: 實際上 C# 也是依照這個概念設計 Class 與 Object 間的關西. - 猜猜看以下程式碼會拋出幾次例外 !? ```C# class MyClass { public static int P { get; set; } = 5; static MyClass() => throw new Exception(); } static void Main(string[] args) { try { MyClass.P = 3; } catch (Exception e) { Console.WriteLine("1 : " + e.Message); } try { var class1 = new MyClass(); } catch (Exception e) { Console.WriteLine("2 : " + e.Message); } try { Console.WriteLine($"{MyClass.P} {MyClass.P}"); } catch (Exception e) { Console.WriteLine("3 : "+e.Message); } } ``` - 輸出結果 ``` 1 : The type initializer for 'MyClass' threw an exception. 2 : The type initializer for 'MyClass' threw an exception. 3 : The type initializer for 'MyClass' threw an exception. ``` - 在執行 ```MyClass.P = 3;``` 時 , 靜態建構子會執行拋出例外 , 這合理, 我們也使用 try catch 接住這個例外了. 但靜態建構子只會執行一次 , 所以在我們原本的設想中 , ```new MyClass();``` 以及 ```{MyClass.P}``` 的使用是不應該拋出例外的 , 那為何會拋出呢 !? - 拋出的原因是第一次執行靜態建構子時, 因為拋出例外, 導致 Class 沒有正常初始化完成. 所以此時的程式是不存在 MyClass 這個型別(模具)的, 故之後任何使用到 MyClass 的運作都會拋出例外. (錯誤訊息為 The type initializer for 'MyClass'). 沒有模具, 何來實體 !? - [What is type initializer exception in c#?](https://technical-qa.com/what-is-type-initializer-exception-in-c/) #### Entity > anything from real world that is significant enough to be represented as a class in the application is referred to as a entity > PS: entity framework 也使用這個詞去表達某個重要 term. (只是使用而已) - Entity 通常用來表示某個具有重要意義的名詞(概念). 不一定只有一個 ![乞丐中的霸主](https://github.com/s0920832252/C_Sharp/blob/master/Files/Note-For-Object-Oriented-Programming-Fundamentals/EntityDemostrate.png?raw=true) 周星馳扮演的蘇乞兒曾經問過乞丐長老一句話 : 乞丐中的霸主是什麼 ?! ![還是乞丐](https://github.com/s0920832252/C_Sharp/blob/master/Files/Note-For-Object-Oriented-Programming-Fundamentals/EntityDemostrate2.png?raw=true) 長老回 : 還是乞丐 XD 這就跟 Entity class 一樣. Entity class 相比一般的 class 的, 其是具有 significant 的, 用來**幫助我們溝通或者更好的抽象化**. 但它還是 class XD ##### 參考資源 [What's the difference between entity and class?](https://stackoverflow.com/a/34459490) > - Class is a syntactic i.e. A set or category of things having some property or attribute in common and differentiated from others by kind, type, or quality. > - Entity is a semantic i.e. relating to meaning in language or logic. An entity is something that exists in itself, actually or potentially, concretely or abstractly, physically or not. It needs not be of material existence. > - Object is a in-memory value referenced by identifier, it is an instance of a Class. > An entity usually refers to something, anything really, that has a unique and separate existence. [Class, Object, Entity: What's the difference?](https://stackoverflow.com/a/14162081) > - A class is a template for creating objects. Not all OO languages use classes (see Self, Javascript). Typically classes are implemented as objects. > - An object is a bundle of data that is packaged with functions that act on that data (called methods). Calling a class's constructor allocates memory for the object and initializes its member variables. > - An entity is an object that represents something that has an identity that the system is interested in tracking. Typical examples are Customers and Accounts. ### Abstraction > Abstraction is the process of defining classes by simplifying reality, ignoring extraneous details, and focuing on what is important for purpose. ![Abstraction](https://github.com/s0920832252/C_Sharp/blob/master/Files/Note-For-Object-Oriented-Programming-Fundamentals/Abstraction.png?raw=true) ##### 參考資源 [抽象化](https://hackmd.io/6hr1KZLRT9aJ6K-BmO7awA?view#%E6%8A%BD%E8%B1%A1%E5%8C%96) ### Encapsulation > - Encapsulation is a way to hide or encapsulation the data and implementation details whithin a clas, thus hiding complexity > - Encapsulation allows the objects in the application to work together without each object knowing the details of other object's implementation > - Encapsulation hides the data and implementation within the class - Protects the data - 外界不能**直接存取**你的 data - Allows for authorization before getting the data - Allows for validation before setting the data - 屬性是語法糖, 實際上是 Set or Get Method. - Help manage complexity - 由類別介面看不出到底實作了什麼, 故可藉由分散實作邏輯到複數個類別 - e.g. A class 有一個方法 DoA() - 執行細節 - DoA 方法執行三個動作 , DoA1 , DoA2 , DoA3. - 外界不知道有三個動作, 外界只在乎 DoA() 執行完後的結果. - 未來可透過抽方法到外部, 降低類別的複雜度. - Only the class needs to understand the implementation - Implementation can be changed without impacting the application ### Coupling > - Coupling is the degree to which classes are dependent on other classes or external resources > - The fewer dependencies the class is , the easier it is to wirte , test , maintain , updte over time > - If there are too many dependencies in a class , consider moving some of those dependencies to another class Low Coupling - there is a reduced probability that changes to one class adversely affects other classes ,making maintenance easier - testing more straightforward because the class has minimal dependencies on the other classes ### Cohesion > - Cohesion is a measure of how related everything in a class is to the purpose of the class > - If there are properties or methods in a class that are not truely related to the purpose of the class , they should be moved to another class High Cohesion - there is a higher probability that a feature request will affect only a smell number of classes , simplifying maintenance - helps produce a focused , well-defined , and complete class , making it easier to understand and test ## Object-Oriented Programming OOP is a approach to designing and building application that are Flexable/Natural/Well-Crafted/Testable by focusing on objects that interact clearly with one another OOP 程式設計的四個步驟 - Identifying classes - 利用抽象化將需求(Requirement) 或規範(Specification) 等概念轉換成類別 <-- 建立 Classes - Separating responsibilities - 分析已有的類別以及試圖分散職責 <-- 讓大類別變小類別 - 可考慮用以下原則去拆分職責 - 單一職責原則 - 關注點分離 - [Non-Fragmented Responsibility Principle](https://zxuanhong.medium.com/%E5%A6%82%E4%BD%95%E6%AA%A2%E9%A9%97%E5%96%AE%E4%B8%80%E8%B2%AC%E4%BB%BB%E5%8E%9F%E5%89%87-%E4%B8%8D%E5%A6%82%E5%8F%8D%E9%81%8E%E4%BE%86%E6%83%B3-42b82a769567) > 軟體中的所有模組不應該共享相同改變的原因。 - 可考慮建立一個新的 class **負責**操作複數個小類別. - Establishing relationship - Defines how objects work together to perform the operations of the application - Leveraging reuse - 抽取共用的邏輯到類別或是元件(Component)以重複使用 - 善用多型 - 定義介面或抽象類別 ### Identifying classes #### Steps From Requirement to Classes - Analyze the business problem - List business terms (they may be entity , may be not) - Start with the nouns - Determine whether these terms should be represented as a entity class - we should give entity class which we created a assumed responsibility (the responsibility may changed , may be not.) - Define appropriate members according assumed responsibility - Define appropriate members for every entity classes - Define properties (data) - Define methods (actions/behaviors) - If we need it , we might create a new class. - e.g. Extract Properties Product & Quantity at class Order into a new class OrderItme - Consider Time (屬性是否會隨著時間而變動) - 考慮類別屬性間的改變是否需要連動 <-- 判斷是否需要調整類別內成員 - 簡單型別 - e.g. Customer 的 Home Address 改變了 , Order 的 Shipping Address 不需要跟著改變 - 參考型別 - e.g. Product 的 Current Price 改變了 , Order Item 的 Product 的 Current Price 不需要跟著改變 - 為 Order Item 新建立一個屬性 Purchase Price - ![AppropriateMembers](https://github.com/s0920832252/C_Sharp/blob/master/Files/Note-For-Object-Oriented-Programming-Fundamentals/AppropriateMembers.png?raw=true) ### Separating responsibilites > - Look at each of the resulting classes and determin whether it is focused or talking on too many responsibility > - Does the class need to do everything specified for it or it should be broken into additional classes - Follow Principle of Separation concerns - e.g. 原本 User class 有 Save 方法(儲存自身的資料) ---> 建一個 UserResposibility Class 負責 User 類別的儲存 ---> User 類別可以專注於自身職責, 而不用負責將自己儲存 - e.g. 原本 User 有一個屬性是 string Address , User 需負責 Address 的格式(像是國家-縣市-區-街/項-號 ...) --->建一個 Address class (擁有 string 國家 , string 縣市 , string 區 ... 等屬性 , ToString 方法去串出正確的地址) ---> User 只需要擁有 Address 成員即可 , 不需要自己處理 Address 格式. - ![Address](https://github.com/s0920832252/C_Sharp/blob/master/Files/Note-For-Object-Oriented-Programming-Fundamentals/Address.png?raw=true) - The Idea is that an application should be decomposed into parts with minimal overlap and each part responsible for a separate concern - Each class is responsible for a separate concern - 每一個類別應該只有一個關注點 <--- SRP #### Benefit - Minimizes coupling - Maximizes cohesion - Simplifies maintenance - Improves testability ### Establishing relationship 決定類別之間應該使用什麼關西來協作 #### Type of Relationships - Collaboration (uses a) - Defines a relationship where one object collaborates with or uses another object that is not otherwise related - ![Collaboration](https://github.com/s0920832252/C_Sharp/blob/master/Files/Note-For-Object-Oriented-Programming-Fundamentals/Collaboration.png?raw=true) - Composition (has a) - Defines the relationship where an object is composed of other objects it needs - A class is made up of parts from other classes - ![Composition](https://github.com/s0920832252/C_Sharp/blob/master/Files/Note-For-Object-Oriented-Programming-Fundamentals/Composition.png?raw=true) - 並不一定要擁有物件 , 只要持有可連結到外部類別的事物, 也算是 Composition 關聯 - e.g. Order 有一個 int Customer Id , 之後使用 Id 透過 CustomerRespository 取回 Customer 物件. 這樣也算是 Order 和 Customer 是 Composition 的關聯. - [[軟工] 類別圖「關聯」、「聚合」及「組合」比較](https://dotblogs.com.tw/lazycodestyle/2016/06/01/233545) - Inheritance (is a) - Inheritance is a feature of object-oriented programming languages that allows you to define a base class that provides specific functionality (data and behavior) and to define derived classes that either inherit or override that functionality. - Define classes that are a more specialized version of another class - ![Inheritance](https://github.com/s0920832252/C_Sharp/blob/master/Files/Note-For-Object-Oriented-Programming-Fundamentals/Inheritance.png?raw=true) - A class can only have one parent class - there can be any number of inheritance levels - Only build an inheritance relationship between calsses if the derived classes have specialized properties or behaviors that require unique code and you can significantly leverage code reuse from the base class <-- 繼承別亂用 (LSP) - Define a base class with common functionality , and derived class inherit from that class to reuse its functionality #### Polymorphism (Inheritance-base) > - Polymorphism allows us to work with groups of classes in a uniform way ##### 參考資源 [什麼是物件導向(3):Polymorphism](http://teddy-chen-tw.blogspot.com/2012/01/3polymorphism.html) > Polymorphism means that the sender of a stimulus does not need to know the receiving instance’s class. The receiving instance can belong to an arbitrary class. > If an instance sends a stimulus to another instance, but does not have to be aware of which class the receiving instance belongs to, we say that we have polymorphism. ### Leveraging reuse - Involves extracting commonality - budinging resusable class or components - 判斷功能是否能夠重複使用 , 若可以, 則應該試圖 Reuse - 建立 Common components 去 Reuse 功能 - 抽取常用功能到新建立的 class library 專案 - e.g. Common or Utility or Helper 專案 - 依據是否需要實體化(是否需要處理個別實體的狀態), 決定是否使用 static Class/Method - 若使用靜態方法 , 可考慮是否使用擴充方法 - Static Method vs Extension Method - Is the primary parameter instance ? - Does the method logically operate on that instance ? - Is it desirable for the method to appear in intelliSense for that type ? - 上述若皆為 yes , 則可以考慮將 static method 改為 擴充方法 - Budilding resusable components - Create a separate project for each reusable component - Build a library of general-purpose methods in the component, grouped into classes - (Library project) - 常建立 static class , 放在 Common Classes - Reuse the component in any application you build - 將能 Resuse 的功能抽到新的類別, 並且建立 Collaboration/Composition 關聯. - ![CustomerAddress](https://github.com/s0920832252/C_Sharp/blob/master/Files/Note-For-Object-Oriented-Programming-Fundamentals/CustomerAddress.png?raw=true) - Defining interfaces (概念的 Reuse )<--- 善用繼承/多型 - ![Inheritance](https://github.com/s0920832252/C_Sharp/blob/master/Files/Note-For-Object-Oriented-Programming-Fundamentals/Inheritance.png?raw=true) ## Summary ### Four Pillars Of OOP ![FourPillarsOfOOP](https://github.com/s0920832252/C_Sharp/blob/master/Files/Note-For-Object-Oriented-Programming-Fundamentals/FourPillarsOfOOP.png?raw=true) - **Abstraction helps us map the business requirements to an intial set of classes** - **Encapsulation helps keep our properties and method code protected within the class and only accessible through a public programming interface** - **Inheritance helps us reuse code by inheriting properties and methods from a base class** - **Polymorphism allow us to write a method with many shapes** ## 雜 ### Step Of Reuse ![StepReuse](https://github.com/s0920832252/C_Sharp/blob/master/Files/Note-For-Object-Oriented-Programming-Fundamentals/StepReuse.png?raw=true) ### Advatages of Reuse ![AdvantagesReuse](https://github.com/s0920832252/C_Sharp/blob/master/Files/Note-For-Object-Oriented-Programming-Fundamentals/AdvantagesReuse.png?raw=true) - Unit Test - 3A 原則 - Arrange : Setup the unit test - Act : Call the method being tested - Assert : Determine the result - 使用測試去保護以及驗證邏輯是否正確 --- ###### Thank you! You can find me on - [GitHub](https://github.com/s0920832252) - [Facebook](https://www.facebook.com/fourtune.chen) 若有謬誤 , 煩請告知 , 新手發帖請多包涵 # :100: :muscle: :tada: :sheep: <iframe src="https://skilltree.my/c67b0d8a-9b69-47ce-a50d-c3fc60090493/promotion?w=250" width="250" style="border:none"></iframe>