您的位置:首页 > 运维架构 > 网站架构

.net架构设计读书笔记--第一章 基础

2016-03-12 00:37 375 查看
第一章 基础

第一节 软件架构与软件架构师

简单的说软件架构即是为客户构建一个软件系统。架构师随便软件架构应运而生,架构师是一个角色。

2000年9月ANSI和IEEE发布了《密集性软件架构建议章程》Recommended practice for architectural description of software-intensive systems

1. 软件架构的目的

2. 架构师的角色与职责

第二节 成功的设计

成功的软件项目是充分实现了软件的需求,成功的软件设计是指成功的软件项目的实践,是根据已知技术设计可重用基础架构的最佳实现。

一、 软件的大泥球

大泥球是一夜之间形成,开始不会很大,它是一个团队的产物。

1. 大泥球形成原因

无法捕捉用户需求
业务需求、 利益相关者的要求、 功能要求、 测试要求

当项目不断增长时仍然坚持使用快速开发

项目开始时可能用户或产品经理承诺需求很简单,不会有变动,这是可能会选择一个简单的架构模式来实现。但随着开发深入,新需求会被不段挖掘出来,这里面监的问题是继续还是重做!

Imprecision of estimates 不精确的估计

在需求规格确认之后又有新的需求扩展,无法与项目预算达成一致

Lack of timely testing 测试的滞后

集成测试问题

2. 大泥球症状

Rigid, therefore fragile 刚性,因此脆弱

Easier to use than to reuse 可重用难

Easier to work around than to fix 变通解决比修复更简单

二、软件的力学原理

什么导致一个软件项目失败?通常会归结于商务上的过失,需求没有明确,项目管理不足、成本估算错误、沟通延时滞后,甚至是人员关系不合!你很难意示到差的软件设计和代码对项目带来的伤害。

1. 组织文化

2. 团队和成员

3. Scrum 消防员

敏捷开过程序遇到的每一个问题都需要快速解决,所以要有人专门来解决这些问题,可能是一个人或是多个人

4. 领导和老板

软件项目成本预算是一个不可回避的问题,项目成本预算包括代码实现、测试、bug fix、文档等等。项目经理管理这些事务,项目汇报对象是项目经理。通常两者都缺乏信任,项目经理认识项目组阻碍项目推进,项目组认为项目经理压缩成本,想用更新钱办更多的事。

领导是一项目技能,领导都不会双向报怨,而是达成一致。

5. 改进团队代码质量

质量差的代码会带来更高的软件成本,因为它涉及到测试,维护,扩展等……

使用工具来改进代码

如何告诉他人他的代码有问题 由于心理方面,直接指证不好,需要沟通技巧

让每个开发人员做的更好 针对代码,而不是针对人员,通过人员素质提升来改进代码,加强培训。

6. 变更是软件项目的一部分

三、走出困境

遗留代码问题

我们经常要面对已有代码,必需要维护它、与新功能集成,这些代码称之遗留代码。

停止新的开发

隔离异常

测试覆盖

持续重构

是否需要添加人员

是否需要延时

第三节 软件设计原则

SOLID原则(Single responsibility, Open/close, Liskov's , Interface segregation, and Dependency inversion).单一职责原则、开放封闭原则、里氏替换原则、接口分离原则、依赖倒置原则

一、从杂乱无章到整理有序

High Cohesion、Low Coupling 高内聚底偶合 单一职责,依赖少,可重用

Separation of concerns 关注点分离 如业务逻辑,展示,持久化。(面向方面设计)

Isolation 隔离 对外隐藏逻辑,使用接口通信

二、Object-oriented design

定义类,评估定义类的颗粒度,定义类接口和继承结构和主要关系。

三、Development and design vectors 开发和设计的方向

1. 设计原则

Single responsibility 单一职责原则

Open/Closed principle 开放封闭原则

通过继承来扩展

Liskov's principle 里氏替换原则

类开基类就可以被替换,子类的行为不能受制于父类。

Interface segregation

接口尽量单一功能,不能所以所有方法放到一个接口里

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;

}

Dependency inversion 依赖倒置

高层模块不应该依赖底层模块都应该依赖于抽象

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

Service Locator pattern 服务定位模式

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) { ... }

}

使用服务定位模式需要慎重考虑,很多情况下,他实际上是个反模式,因为它依赖类的具体引用。

Dependency Injection pattern 依赖注入模式

更好的选择是使用依赖注入模式

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 接口设计应该设计为准备,不应该去问能给我什么数据

什么是设计模式?

设计模式是适用于软件过程中解决一系列问题的核心解决方案

四、Defensive programming 防御性编程
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: