第一章 基礎 編程
第一節 軟件架構與軟件架構師 設計模式
簡單的說軟件架構便是爲客戶構建一個軟件系統。架構師隨便軟件架構應運而生,架構師是一個角色。 架構
2000年9月ANSI和IEEE發佈了《密集性軟件架構建議章程》Recommended practice for architectural description of software-intensive systems 工具
1. 軟件架構的目的 測試
2. 架構師的角色與職責 編碼
第二節 成功的設計spa
成功的軟件項目是充分實現了軟件的需求,成功的軟件設計是指成功的軟件項目的實踐,是根據已知技術設計可重用基礎架構的最佳實現。 設計
1、 軟件的大泥球 對象
大泥球是一晚上之間造成,開始不會很大,它是一個團隊的產物。 繼承
1. 大泥球造成緣由
業務需求、 利益相關者的要求、 功能要求、 測試要求
項目開始時可能用戶或產品經理承諾需求很簡單,不會有變更,這是可能會選擇一個簡單的架構模式來實現。但隨着開發深刻,新需求會被不段挖掘出來,這裏面監的問題是繼續仍是重作!
在需求規格確認以後又有新的需求擴展,沒法與項目預算達成一致
集成測試問題
2. 大泥球症狀
Rigid, therefore fragile 剛性,所以脆弱
Easier to use than to reuse 可重用難
Easier to work around than to fix 變通解決比修復更簡單
2、軟件的力學原理
什麼致使一個軟件項目失敗?一般會歸結於商務上的過失,需求沒有明確,項目管理不足、成本估算錯誤、溝通延時滯後,甚至是人員關係不合!你很難意示到差的軟件設計和代碼對項目帶來的傷害。
1. 組織文化
2. 團隊和成員
3. Scrum 消防員
敏捷開過程序遇到的每個問題都須要快速解決,因此要有人專門來解決這些問題,多是一我的或是多我的
4. 領導和老闆
軟件項目成本預算是一個不可迴避的問題,項目成本預算包括代碼實現、測試、bug fix、文檔等等。項目經理管理這些事務,項目彙報對象是項目經理。一般二者都缺少信任,項目經理認識項目組阻礙項目推動,項目組認爲項目經理壓縮成本,想用更新錢辦更多的事。
領導是一項目技能,領導都不會雙向報怨,而是達成一致。
5. 改進團隊代碼質量
質量差的代碼會帶來更高的軟件成本,由於它涉及到測試,維護,擴展等……
6. 變動是軟件項目的一部分
3、走出困境
咱們常常要面對已有代碼,必須要維護它、與新功能集成,這些代碼稱之遺留代碼。
第三節 軟件設計原則
SOLID原則(Single responsibility, Open/close, Liskov's , Interface segregation, and Dependency inversion).單一職責原則、開放封閉原則、里氏替換原則、接口分離原則、依賴倒置原則
1、從雜亂無章到整理有序
High Cohesion、Low Coupling 高內聚底偶合 單一職責,依賴少,可重用
Separation of concerns 關注點分離 如業務邏輯,展現,持久化。(面向方面設計)
Isolation 隔離 對外隱藏邏輯,使用接口通訊
2、Object-oriented design
定義類,評估定義類的顆粒度,定義類接口和繼承結構和主要關係。
3、Development and design vectors 開發和設計的方向
1. 設計原則
經過繼承來擴展
類開基類就能夠被替換,子類的行爲不能受制於父類。
接口儘可能單一功能,不能因此全部方法放到一個接口裏
public interface IDoor
{
void Lock();
void Unlock();
Boolean IsDoorOpen { get; }
Int32 OpenTimeout { get; set; }
event EventHandler DoorOpenForTooLong;
}
應該分紅兩個接口
public interface IDoor
{
void Lock();
void Unlock();
Boolean IsDoorOpen { get; }
}
public interface ITimedDoor
{
Int32 OpenTimeout { get; set; }
event EventHandler DoorOpenForTooLong;
}
高層模塊不該該依賴底層模塊都應該依賴於抽象
2、依賴處理模式 Patterns for handling dependencies
void Copy()
{
Byte byte;
while(byte = ReadFromStream())
WriteToBuffer(byte);
}
reader和writer依賴於底層實現,強偶合,按照依賴倒置原則應該改成如下代碼
void Copy()
{
Byte byte;
IReader reader;
IWriter writer;
// Still need to instantiate reader and writer variables
...
while(byte = reader.Read())
writer.Write(byte);
}
誰來實現reader和writer
void Copy()
{
Byte byte;
var reader = ServiceLocator.GetService<IReader>();
var writer = ServiceLocator.GetService<IWriter>();
while(byte = reader.Read())
writer.Write(byte);
}
ServiceLocator返回具體類,相似工場做用,ServiceLocator可能以下實現
public class ServiceLocator
{
public Object GetService(Type typeToResolve) { ... }
public T GetService<T>() { ... }
public Object GetService(String typeNickname) { ... }
}
使用服務定位模式須要慎重考慮,不少狀況下,他其實是個反模式,由於它依賴類的具體引用。
更好的選擇是使用依賴注入模式
void Copy(IReader reader, IWriter writer)
{
Byte byte;
while(byte = reader.Read())
writer.Write(byte);
}
2.編碼原則
Keep It Simple, Stupid
You Ain't Gonna Need It
Don't Repeat Yourself
Tell, don't ask 接口設計應該設計爲準備,不該該去問能給我什麼數據
什麼是設計模式?
設計模式是適用於軟件過程當中解決一系列問題的核心解決方案
4、Defensive programming 防護性編程