架構師訓練營 week2 總結
1. 从编程历史看面向对象编程的本质与未来
Goal of programing
use a computer to solve problems of the real world
Process of programing:
build the relationship between “computer’s model” and questions of the real world.
Programing is an “abstract” mechanism, the question is “abstract whom"
What is OOP?
Everything is an object
Objects communicate only by sending each other messages
Every object is an instance of a class.
Classes are used to define the set of messages an instance of that class responds to, as well as the variables contained in every instance of that class
What is Object?
state: each object can have its own data
behavior: each object can do something
Identity: every object is different (uniq address)
3 factors of OOP
Encapsulation
Hide implementation detail
Inheritance
IS-A
Polymorphism
the sender of a stimulus does not need to know the receiving instance’s class. The receiving instance can belogin to an arbitrary class
The goals of OOP
high cohesion and low coupling
Extend: easy to add a new feature
Strong
Porting: can run in different environments
Simple: easy to understand and maintain
Frameworks
A tool that allows to develop software and create systems.
An Implementation of a real architecture design
Provide some design patterns, let developers design a good program easily
Frameworks VS Library
a framework uses programming code
Programing code uses a library
The architect uses a framework to make sure architecture landing
The architect uses the library to improve the effectiveness
2. 糟糕的代码有哪些特点?
Bad smell code
Rigidity: not easy to update
Rigid code is resistance to change, change it, and you have to change something else
Fragility: update A but break B
Fragile code breaks due to external changes or untested uses of the system
Immobility: hard to reuse
Viscosity: changes or additions are easier to implement by doing the wrong thing
Opacity
Needless Complexity
Needless Repetition
One bad case
Copy from keyboard and write to printer
it should be
Abstract “Copy”
Copy from where => Reader
Copy to where => Writer
One use case
我們按下數字按鈕,屏幕上顯示號碼,揚聲器發出按鍵音
我們按下 send 按鈕,系統接通無線網路,同時銀幕顯示正在撥號
所有的名詞都可能是潛在的對象,誰是使用系統的主要功能者
可以進行交互,上面有行為的東西才能成為對象
先找出名詞:
數字按鈕
屏幕
號碼 => 不能交互、沒有行為
揚聲器
按鍵音 => 不能交互、沒有行為
Send 按鈕
系統 => 代表整個系統,所以也不用算在物件裡面
無線網路 => 不能交互、沒有行為
What is the problem:
Rigidity
If I want to add one more “Button" type, I need to update the button class
If I update Dialer, it might affect “Button"
Fragility
Switch, if/else is fragile
Immobility
Buttons of coded lock only need digit buttons, but the current design let them have to have “send” button
3. 开闭原则介绍及代码分析
OCP: Open/Closed Principle
Open for extension
Extend Module, Class, Method
Closed for modification
Not update current Module, Class, Method
What we need to do it let modification can be more “concentrated", “fewer”, “in high level”. Let the most complicated logic part to meet OCP
We should always think about “Extension”, “Abstraction”, “Encapsulation"
Encapsulate changeable part and provide abstract non-changeable interface
sample code
4. 依赖倒置原则介绍及代码案例分析
DIP: Dependency Inversion Principle
High-level modules should not depend on low-level modules. Both should depend on abstractions.
Abstractions should not depend on details. Details should depend on abstractions.
What does “Inversion” do?
Dependence of modules
Order and responsibility of development
Hierarchical software design
High level module decide low level module
當我們設計框架時,要時時記住依賴倒置原則。
找出目前物件的本質,設計出接口
Button 的本質是什麼
檢測用戶的案件指令,並傳遞給目標對象
用什麼機制檢測 => 不重要 => 由不同的低層模塊實現、擴展
目標對象是什麼 => 不重要 => 由不同的低層模塊實現、擴展
它幫助我們專注於高層的設計,並且提醒我們高層不應該依賴於低層,永遠要設計抽象化接口
Ex:
Tomcat (high level) and Java Web (low level)
Both rely on “Servlet specification"
“Servlet specification” does not rely on the detail of Tomcat or Java Web
5. 里氏替换原则
子類可以替換父類,那繼承就是合理的
子類完美繼承父類的設計初衷,並做了增強
Design by contract
Child class design should follow the father's class’s contract. Father defines the behavior of the function, then the child can update the detailed logic, but the child can’t update the original behavior.
Input, output, error handling.
Child <-> Father => Implementation <-> Interface
設計和界定一個類,應該以其行為作為區分
When you design and define classes, you should use “behavior” to define different classes
How to fix the LSP issue?
Put the same behaviors to a base class
Use assembly instead of inherited
How to validate LSP?
Check from the context
6 单一职责接口隔离
SRP: Single Responsibility Principle
There should never be more than one reason for a class to change.
Anti patten
fix it
How to separate classes?
clarify the responsibility
出現這些情況,容易不符合 SRP
類中的代碼行數、函數或者屬性過多;
類依賴的其他類過多,或者依賴類的其他類過多;
私有方法過多;
比較難給類起一個合適的名字;
類中大量的方法都是集中操作類中的某幾個屬性。
ISP: Interface Segregation Principlew
Clients should not be forced to depend upon interfaces that they do not use
接口
一組 API 接口集合
在設計為服務或者類庫接口的時候,如果部分接口只被部分調用者使用,那我們就需要將這部分接口隔離出來,單獨給對應的調用者使用,而不是強迫其他調用者也依賴這部份不會被用到的接口
單個 API 的接口或函數
函數的設計要功能單一,不要將多個不同的功能邏輯在一個函數中實現
OOP 中的接口概念
接手的設計要盡量單一,不要讓接口的實現類和調用者,依賴不需要的接口函數
ISP and SRP
Related cohesion
SRP => how to design a class => There should never be more than one reason for a class to change.
ISP => how to design an interface => from clients' view, they should not be forced to depend upon interfaces that they do not use
It is very difficult to fully meet SRP, but we still can use ISP to separate to different interfaces and then limit the effect scope when changing
评论