CPP-Summit-2020 学习:System Architecture And Design
空间 (Space) 的定义
定义:空间是定义可能性的关注梯度(gradient of concerns)。
用数学的角度理解,如果空间是多维的,每一个维度对应一个关注点,那么空间 SSS 可以表示为一个向量空间:
S=(c1,c2,…,cn) S = (c_1, c_2, \dots, c_n) S=(c1,c2,…,cn)
其中 cic_ici 表示第 iii 个关注点,nnn 是关注点的数量(维度)。
空间决定 (Space dictates)
空间会影响:
- 概念的呈现
哪些概念可以被讨论和表示。 - 可能的议题和解决方案
哪些问题可以被提出,哪些解决方案可以被考虑。
空间的性质 (N维性)
空间通常是 N 维的,即多维的,每个维度对应一个不同的关注点。
- 每个关注点可能 加权 (weighted):
wi⋅ci w_i \cdot c_i wi⋅ci
其中 wiw_iwi 是第 iii 个关注点的权重。 - 每个关注点可能 排序 (ranked):
不同关注点的重要性可以通过排序体现。
代码注释示例(Python 表示空间及权重):
# 定义一个空间 S,由多个关注点组成,每个关注点有权重classSpace:def__init__(self, concerns, weights): self.concerns = concerns # 关注点列表 self.weights = weights # 对应权重assertlen(concerns)==len(weights),"关注点和权重数量必须相同"空间的隐含性 (Space implies)
- 空间隐含了哪些问题和解决方案 可以讨论。
- 空间表示的领域是探索这些问题和解决方案的范围。
- 空间也隐含了 不可见的议题或解决方案:
- 正交问题 (orthogonal issue):某些问题与当前空间不相关,无法在该空间中讨论。
- 不可描述或不可解决问题:需要在另一个空间中管理。
数学上可以表示为:
如果 x⊥S,则 x不在该空间的讨论范围内 \text{如果 } x \perp S, \text{则 } x \text{不在该空间的讨论范围内} 如果 x⊥S,则 x不在该空间的讨论范围内
开发空间 / 建筑空间 / 设计空间对比
| 空间类型 | 定义 | 特点 |
|---|---|---|
| 开发空间 (Development Space) | 软件或产品开发相关的可能性空间 | 关注实现、功能、可行性 |
| 建筑空间 (Architectural Space) | 架构层面的可能性空间 | 关注系统结构、模块关系 |
| 设计空间 (Design Space) | 设计决策与创意的可能性空间 | 关注用户体验、创新方案 |
每个空间都有自己的关注点集合 S=(c1,…,cn)S = (c_1, \dots, c_n)S=(c1,…,cn),并且它们的维度、权重和排序方式可能完全不同。
从开发者角度思考 (Think in Terms of Developers)
作为开发者,我们在思考问题时,会用不同的“视角”来分析:
1. 编程语言 (Programming Language)
- 我们思考的是 语法规则和语义规则
- 即:如何用语言的结构和意义来表达问题和解决方案
数学上可以表示为:
L=语法规则,语义规则 L = { \text{语法规则}, \text{语义规则} } L=语法规则,语义规则
C++ 示例(语法与语义规则):
#include<iostream>usingnamespace std;// 语法规则:函数定义、循环结构// 语义规则:变量作用域、类型安全intadd(int a,int b){return a + b;// 返回两个数的和}intmain(){int result =add(5,3); cout <<"Result: "<< result << endl;return0;}2. 编程范式 (Paradigm)
- 解释为:如何思考问题
- 帮助我们分解问题、组织逻辑
常见范式: - 面向对象 (OOP)
- 函数式编程 (Functional)
- 面向过程 (Procedural)
数学表示问题分解:
P=Problem ⟹ sub_problem1,sub_problem2,… P = \text{Problem} \implies { sub\_problem_1, sub\_problem_2, \dots } P=Problem⟹sub_problem1,sub_problem2,…
C++ 中面向对象示例:
classShape{public:virtualdoublearea()=0;// 子类必须实现};classCircle:publicShape{double radius;public:Circle(double r):radius(r){}doublearea()override{return3.1415* radius * radius;// 面积计算}};3. 问题 (The Problem)
- 对开发者而言,问题主要是 技术性的
- 需要解决的技术和人体工程学(ergonomic)问题
数学上可以表示为:
Problem=Technical concerns,Ergonomic concerns \text{Problem} = { \text{Technical concerns}, \text{Ergonomic concerns} } Problem=Technical concerns,Ergonomic concerns
C++ 示例(技术问题:计算与接口):
// 技术问题: 计算精度、效率doubledivide(double a,double b){if(b ==0)throwruntime_error("除数不能为零");return a / b;}作为有经验的开发者 (As Experienced Developers)
经验丰富的开发者,会进一步考虑 开发过程和团队协作:
1. 开发过程 (Process)
- 包括传统和迭代的领域探索 (Traditional and Iterative domain exploration)
- 思考问题的空间随着过程变化而变化
数学上可以表示为动态空间:
St=f(process at time t) S_t = f(\text{process at time t}) St=f(process at time t)
2. 角色 (Roles)
- 不同参与方的互动也会影响空间和解决方案
- 即开发空间是 多主体、多维度的交互空间
3. 空间的维度 (Dimensions defining the spaces)
- 空间的维度定义了:
- 问题被定义的范围
- 解决方案被表达的方式
用 C++ 类比:
// 定义问题空间的维度structProblemSpace{bool technicalConcern;bool ergonomicConcern;bool businessConstraint;};structSolutionSpace{bool algorithmicSolution;bool architecturalDesign;bool UIUXDesign;};空间的本质
- 开发空间 (Development Space):关注技术实现、编程语言、问题解决
- 架构空间 (Architectural Space):关注系统结构、模块关系
- 设计空间 (Design Space):关注用户体验、业务协调和约束管理
数学表示不同空间:
Development Space SD=L,P,Technical ProblemsArchitectural Space SA=Structure,ModulesDesign Space SDes=Business,UX,Constraints \text{Development Space } S_D = { L, P, \text{Technical Problems} } \\ \text{Architectural Space } S_A = { \text{Structure}, \text{Modules} } \\ \text{Design Space } S_{Des} = { \text{Business}, \text{UX}, \text{Constraints} } Development Space SD=L,P,Technical ProblemsArchitectural Space SA=Structure,ModulesDesign Space SDes=Business,UX,Constraints
✓ 总结
从开发者角度:
- 语言层面:语法与语义
- 思维范式:如何拆解问题
- 问题本身:技术和人体工学
从有经验开发者角度: - 开发过程:迭代与传统探索
- 角色和协作:多方互动
- 空间维度:问题和解决方案被定义与表达的空间
所有这些共同形成了 开发空间、架构空间、设计空间 的完整理解。
角色 (Role)
定义 (def):角色是执行某个功能或承担某个部分的身份。
示例角色 (Example roles):
- 开发者 (Developer)
- 设计师 (Designer)
- 域专家 (Domain Expert)
- 架构师 (Architect)
- 产品负责人 (Product Owner)
- 客户倡导者 (Customer Advocate)
- 经理 (Manager)
- 高管 (Executive Owner)
角色决定 (Role dictates)
角色会决定:
- 你关心什么
- 你负责什么
数学上可以用集合表示一个角色的关注点:
Crole=关注点1,关注点2,… C_{role} = {\text{关注点}_1, \text{关注点}_2, \dots } Crole=关注点1,关注点2,…
C++ 代码示例:
#include<iostream>#include<vector>#include<string>usingnamespace std;// 定义角色及其关注点structRole{ string name;// 角色名称 vector<string> concerns;// 关注点列表};intmain(){ Role developer ={"Developer",{"C++ features","Technical solutions","Implementation"}}; Role designer ={"Designer",{"Design approach","System paradigms","Code evolution"}}; cout << developer.name <<" concerns:"<< endl;for(auto&c : developer.concerns) cout <<"- "<< c << endl;}角色隐含 (Role implies)
- 每个角色的关注点是独特的(不同角色有不同的关注)
- 必须与其他角色交互(其他角色关心不同但可能重叠的关注点)
数学上可以表示为:
Interaction(Ri,Rj)=CRi∩CRj(交集表示重叠关注点) \text{Interaction}(R_i, R_j) = C_{R_i} \cap C_{R_j} \quad \text{(交集表示重叠关注点)} Interaction(Ri,Rj)=CRi∩CRj(交集表示重叠关注点)
角色随时间变化 (Roles Change Over Time)
不同阶段的开发者角色关注点不同:
新开发者 (New Developers)
主要关注:
- C++ 语言特性如何工作
- 如何实现技术方案
- 哪种实现方式最好
特点:需要学习技术技能,探索空间很大。
// 技术技能学习示例:了解C++特性intmain(){auto lambda =[](int x){return x*x;};// C++ lambda表达式 cout <<lambda(5)<< endl;}设计师 (Designers)
主要关注:
- 系统应采用哪种设计方法
- 使用什么编程范式(思考问题的方式)
- 代码如何演进以支持新的设计理念
- 如何解决过去遗留的问题
数学上,设计师关注的是 Design Space:
Sdesign=设计方法,编程范式,代码演进,新旧问题解决 S_{design} = {\text{设计方法}, \text{编程范式}, \text{代码演进}, \text{新旧问题解决}} Sdesign=设计方法,编程范式,代码演进,新旧问题解决
架构师 (Architects)
主要关注:
- 系统应该做什么
- 应该利用哪些技术来实现系统功能
- 代码和模块的重用
- 组织的技术演进
主要考虑因素:
- 解决方案空间 (Solution Space)
- 产品空间 (Product Space)
- 组织健康 (Organizational Health)
次要考虑因素: - 外部技术环境(包括 C++ 语言的更新)
数学上可表示为多维度空间:
Sarchitect=Solution Space,Product Space,Organizational Health,External Tech Landscape S_{architect} = {\text{Solution Space}, \text{Product Space}, \text{Organizational Health}, \text{External Tech Landscape}} Sarchitect=Solution Space,Product Space,Organizational Health,External Tech Landscape
C++ 示例(架构师角度思考技术复用):
// 技术复用示例:模板类复用算法逻辑template<typenameT>classRepository{public:voidadd(T item){ data.push_back(item);} T get(int index){return data[index];}private: vector<T> data;};intmain(){ Repository<int> repo; repo.add(10); cout << repo.get(0)<< endl;}总结:角色与关注点映射
| 角色 | 关注点 | 示例 |
|---|---|---|
| 新开发者 | C++ 特性、实现方法、最佳实践 | 技术技能获取 |
| 设计师 | 设计方法、编程范式、代码演进 | 解决设计问题 |
| 架构师 | 系统目标、技术选型、重用、组织发展 | 系统架构设计 |
公式表示各角色的关注空间:
CDeveloper=C++特性, 实现, 技术解决方案CDesigner=设计方法, 编程范式, 代码演进CArchitect=解决方案空间, 产品空间, 组织健康, 技术环境 C_{Developer} = {\text{C++特性, 实现, 技术解决方案}} \\ C_{Designer} = {\text{设计方法, 编程范式, 代码演进}} \\ C_{Architect} = {\text{解决方案空间, 产品空间, 组织健康, 技术环境}} CDeveloper=C++特性, 实现, 技术解决方案CDesigner=设计方法, 编程范式, 代码演进CArchitect=解决方案空间, 产品空间, 组织健康, 技术环境
交互公式:
Roles Interaction=CDeveloper∩CDesigner∩CArchitect \text{Roles Interaction} = C_{Developer} \cap C_{Designer} \cap C_{Architect} Roles Interaction=CDeveloper∩CDesigner∩CArchitect
关注 C++ 语言演进 (Caring About C++ Language Evolution)
所有角色的开发者都会关心 C++ 语言特性,但关注的重点因角色而异。
1. 新开发者 (New Developer)
关注点:
- 如何完成我的工作?
- 关注具体语法和功能实现,解决日常开发问题。
- 最佳实践是什么?
- 关注如何使用最新语言特性以编写可靠且可维护的代码。
C++ 示例:
- 关注如何使用最新语言特性以编写可靠且可维护的代码。
#include<iostream>#include<vector>usingnamespace std;// 新开发者关注:如何使用C++特性完成任务intmain(){ vector<int> nums ={1,2,3,4,5};// 使用C++11范围for循环 (range-based for) 特性for(int n : nums){ cout << n <<" ";} cout << endl;return0;}数学上,新开发者关注的空间可以表示为:
CNewDev=任务完成,最佳实践,语言特性使用 C_{NewDev} = {\text{任务完成}, \text{最佳实践}, \text{语言特性使用}} CNewDev=任务完成,最佳实践,语言特性使用
2. 有经验的设计师 (Experienced Designer)
关注点:
- 现在有哪些设计习惯 (Design idioms) 可用?
- 关注新的 C++ 特性如何改变设计方式。
- 我现在可以解决哪些问题?
- 关注是否能用更稳健(robust)或更优雅(elegant)的方式解决问题。
C++ 示例(设计师视角):
- 关注是否能用更稳健(robust)或更优雅(elegant)的方式解决问题。
#include<iostream>#include<memory>usingnamespace std;// 智能指针是C++11新增设计习惯structNode{int value; shared_ptr<Node> next;// 用shared_ptr管理内存更安全};intmain(){auto n1 =make_shared<Node>(); n1->value =42;auto n2 =make_shared<Node>(); n1->next = n2;// 安全连接节点 cout << n1->next->value << endl;// 输出42}数学表示设计师关注的空间:
CDesigner=设计习惯,新问题解决方案,代码优雅性 C_{Designer} = {\text{设计习惯}, \text{新问题解决方案}, \text{代码优雅性}} CDesigner=设计习惯,新问题解决方案,代码优雅性
3. 架构师 (Architect)
关注点:
- C++ 语言特性如何影响系统架构?
- 例如,是否使用 C++ 优于其他语言(或硬件实现子系统)?
- 如何利用新的语言特性进行硬件/软件的最优组合?
- 考虑系统整体效率、可维护性和未来演进。
数学上可以表示为:
CArchitect=语言选择,硬件/软件结合,系统架构优化 C_{Architect} = {\text{语言选择}, \text{硬件/软件结合}, \text{系统架构优化}} CArchitect=语言选择,硬件/软件结合,系统架构优化
C++ 示例(架构师视角,考虑语言特性与系统选择):
- 考虑系统整体效率、可维护性和未来演进。
#include<thread>#include<vector>#include<iostream>usingnamespace std;// 架构师关注:利用C++多线程特性提升系统性能voidworker(int id){ cout <<"Thread "<< id <<" is running."<< endl;}intmain(){ vector<thread> threads;for(int i =0; i <4; i++){ threads.emplace_back(worker, i);}for(auto&t : threads) t.join();return0;}总结:不同角色对 C++ 演进的关注
| 角色 | 关注点 | 目标 |
|---|---|---|
| 新开发者 | 如何完成工作,最佳实践 | 学会语言特性,解决日常开发问题 |
| 有经验设计师 | 新设计习惯,可优雅解决问题 | 改进设计模式,提高代码质量 |
| 架构师 | 系统架构、语言选择、硬件/软件协作 | 优化系统架构,提高性能和可维护性 |
公式表示整体交互空间:
CC++=CNewDev∪CDesigner∪CArchitect C_{C++} = C_{NewDev} \cup C_{Designer} \cup C_{Architect} CC++=CNewDev∪CDesigner∪CArchitect
- ∪\cup∪ 表示不同角色关注点的组合
- 各角色关注点可能有 重叠,也可能有独特关注
开发者视角下的角色 (Developer’s Perspective of Roles)
问题 (Q):有经验的设计师 (Experienced Designer) 和架构师 (Architect) 有什么不同?
1. 架构师 (Architect)
关注点:
- 业务方向 (Business Direction)
架构师不仅关注技术实现,还要考虑整个系统与组织战略、业务目标的对齐。 - 关注 系统架构、技术选型、组织演进。
数学上可以表示架构师的关注空间:
CArchitect=Business Direction, Solution Space, Product Space, Organizational Health C_{Architect} = {\text{Business Direction, Solution Space, Product Space, Organizational Health}} CArchitect=Business Direction, Solution Space, Product Space, Organizational Health
C++ 示例(架构师关注业务和技术结合):
#include<iostream>#include<thread>usingnamespace std;// 架构师角度:考虑业务需求,决定使用多线程提升性能voidprocessTask(int id){ cout <<"Processing task "<< id <<" efficiently."<< endl;}intmain(){ thread t1(processTask,1); thread t2(processTask,2); t1.join(); t2.join();}2. 有经验的设计师 (Experienced Designer)
关注点:
- 成功的技术交付 (Successful Technical Delivery)
- 设计师关注系统设计和技术实现的质量
- 如何使用新语言特性和设计方法保证系统可维护、可扩展
数学上可以表示设计师的关注空间:
CDesigner=Technical Delivery, Design Patterns, Code Evolution C_{Designer} = {\text{Technical Delivery, Design Patterns, Code Evolution}} CDesigner=Technical Delivery, Design Patterns, Code Evolution
C++ 示例(设计师关注设计与交付):
#include<iostream>#include<memory>usingnamespace std;// 设计师角度:设计模式与资源管理classLogger{public:static Logger&getInstance(){static Logger instance;// 单例模式return instance;}voidlog(const string& message){ cout << message << endl;}private:Logger(){}};intmain(){Logger::getInstance().log("Delivering quality technical solution");}3. 新开发者 (New Developer)
关注点:
- 对各种“闪亮的技术点”感到好奇,但尚未能区分重要性
- 关注点比较分散,主要在理解语言特性和基础实现
数学表示新开发者关注空间:
CNewDev=Learning C++ features, Implementation, Exploration C_{NewDev} = {\text{Learning C++ features, Implementation, Exploration}} CNewDev=Learning C++ features, Implementation, Exploration
C++ 示例(新开发者探索语言特性):
#include<iostream>#include<vector>usingnamespace std;// 新开发者探索C++特性intmain(){ vector<int> nums ={1,2,3};for(auto n : nums){// 范围for循环 C++11特性 cout << n << endl;}}总结:角色关注点的差异
| 角色 | 核心关注点 | 数学表示 |
|---|---|---|
| 架构师 | 业务方向、系统架构、组织演进 | CArchitect=Business Direction, Solution Space, Product Space, Organizational HealthC_{Architect} = {\text{Business Direction, Solution Space, Product Space, Organizational Health}}CArchitect=Business Direction, Solution Space, Product Space, Organizational Health |
| 有经验设计师 | 技术交付、设计模式、代码演进 | CDesigner=Technical Delivery, Design Patterns, Code EvolutionC_{Designer} = {\text{Technical Delivery, Design Patterns, Code Evolution}}CDesigner=Technical Delivery, Design Patterns, Code Evolution |
| 新开发者 | 学习语言特性、实现、探索 | CNewDev=Learning C++ features, Implementation, ExplorationC_{NewDev} = {\text{Learning C++ features, Implementation, Exploration}}CNewDev=Learning C++ features, Implementation, Exploration |
公式关系:
- 不同角色关注点可能重叠或独特:
CArchitect∩CDesigner≠∅ CNewDev可能重叠或独立于其他角色 C_{Architect} \cap C_{Designer} \neq \emptyset \ C_{NewDev} \text{可能重叠或独立于其他角色} CArchitect∩CDesigner=∅ CNewDev可能重叠或独立于其他角色
开发概览 (Development Overview)
在软件开发中,开发过程涉及一系列 工件 (Artifacts) 和 角色 (Roles),每个环节产生不同的成果:
1. 问题空间 (Problem Space)
- 描述 业务需求,定义系统需要解决什么问题。
- 输出:需求文档 (Requirements Analysis / RFP)
数学表示问题空间:
P=Business Needs P = {\text{Business Needs}} P=Business Needs
C++ 示例(表示问题空间):
structProblem{ std::string businessNeed;// 业务需求描述}; Problem problem ={"客户需要一个高性能数据处理系统"};2. 系统分析 (System Analysis)
- 从问题空间出发,分析系统应该如何工作。
- 输出:技术细节 (Technical Details),确定“如何解决问题”。
数学表示系统分析空间:
S=f(P)=Technical Details, Solution Approach S = f(P) = {\text{Technical Details, Solution Approach}} S=f(P)=Technical Details, Solution Approach
C++ 示例:
structSystemAnalysis{ std::string technicalSolution;// 技术解决方案 std::string approach;// 分析方法}; SystemAnalysis analysis ={"使用多线程处理数据","C++11线程库"};3. 架构与设计 (Architecture & Design)
- 基于系统分析,提出 架构与设计方案 (Proposed Architecture & Design Proposal)
- 输出:架构图、模块设计、技术方案可交付成果
数学表示:
A=g(S)=Architecture, Design, Modules, Interfaces A = g(S) = {\text{Architecture, Design, Modules, Interfaces}} A=g(S)=Architecture, Design, Modules, Interfaces
C++ 示例(架构与设计阶段):
#include<vector>#include<memory>structModule{ std::string name; std::vector<std::string> dependencies;};structArchitecture{ std::vector<Module> modules;}; Architecture arch; arch.modules.push_back({"DataProcessor",{"InputModule","OutputModule"}});4. 实现 (Implementation)
- 根据架构与设计构建系统
- 参与角色:开发者 (Developers)、设计师 (Designers)、架构师 (Architects)
数学表示实现空间:
I=h(A)=Code, Tests, Executable System I = h(A) = {\text{Code, Tests, Executable System}} I=h(A)=Code, Tests, Executable System
C++ 示例(实现阶段):
#include<iostream>usingnamespace std;// 实现DataProcessor模块classDataProcessor{public:voidprocess(int data){ cout <<"Processing data: "<< data << endl;}};intmain(){ DataProcessor dp; dp.process(42);}5. 交付 (Delivery / Ship It!)
- 系统完成后交付使用
- 需要满足业务需求,行为符合预期
数学表示交付成果:
D=deliver(I)满足 P D = deliver(I) \quad \text{满足 } P D=deliver(I)满足 P
C++ 示例(交付后的验证):
#include<cassert>intmain(){int result =42;// 系统处理结果assert(result ==42);// 验证满足业务需求}角色与责任 (Roles & Responsibilities)
- 业务领导 (Business Leadership):确定问题空间中的优先级
- 技术领导 (Architects & Designers):管理技术实现,确保架构与设计符合需求
- 开发者 (Developers):执行具体实现
公式表示角色与空间映射:
Business Leadership→PTechnical Leadership→S∪ADevelopers→I \text{Business Leadership} \to P \\ \text{Technical Leadership} \to S \cup A \\ \text{Developers} \to I Business Leadership→PTechnical Leadership→S∪ADevelopers→I
注意:在实际开发中,角色责任可能混淆,受到约束条件 (Constraints)、偏好 (Preferences) 和能力 (Capabilities) 的影响。
“旧时代”开发流程 (The Olden Days)
| 阶段 | 输出 | 主要负责角色 |
|---|---|---|
| 需求分析 (Requirements Analysis) | 系统应做什么 (WHAT) | 业务经理 (Business Managers) |
| 架构与设计 (Architecture & Design) | 提议架构和设计方案 (HOW) | 架构师 & 设计师 |
| 实现 (Implementation) | 构建系统 | 架构师 & 设计师 & 开发者 |
| 交付 (Delivery) | 系统可用 | 所有技术角色 |
流程视图对比 (WHAT vs HOW)
- WHAT:需求分析 → 提供给架构师/设计师系统应该做什么
- HOW:架构与设计 → 系统分析 + 提议架构 → 实现 → 交付
数学表示:
WHAT=PHOW=h(g(f(P)))=I→D \text{WHAT} = P \\ \text{HOW} = h(g(f(P))) = I \to D WHAT=PHOW=h(g(f(P)))=I→D
fff:系统分析
ggg:架构与设计
hhh:实现
永远不要混淆 (Never Mix / Should Not Mix)
“当你混合本不该混合的东西时,坏事情就会发生™”
核心原则
- 有些事情 绝对不能混合 (NEVER MIX)
- 你必须 始终清楚自己在做“哪一件事”
- 如果发现不确定自己在做什么,立即停止并弄清楚
WHAT vs HOW
- WHAT (系统需求 / System Requirements)
- 描述 系统必须做什么
- 关注业务需求和问题定义
- 数学表示:
WHAT=Business Needs, Functional Requirements WHAT = {\text{Business Needs, Functional Requirements}} WHAT=Business Needs, Functional Requirements
- HOW (架构与设计 / Architecture & Design)
- 描述 系统如何实现
- 关注技术实现、可行性和开发方案
- 数学表示:
HOW=Architecture, Design, Implementation Details HOW = {\text{Architecture, Design, Implementation Details}} HOW=Architecture, Design, Implementation Details
重要原则:
NEVER MIX(WHAT,HOW) \text{NEVER MIX}(WHAT, HOW) NEVER MIX(WHAT,HOW)
即不要在讨论“系统必须做什么”的同时,去考虑“系统如何实现”,否则会导致混乱。
扩展注意事项
- 可行性 (FEASIBILITY)
- 在 HOW 阶段,才考虑技术可行性
- WHAT 阶段不要去做可行性分析
- 开发 (DEVELOPMENT)
- 构建系统的阶段
- 只能基于 HOW 进行,不应该在 WHAT 阶段做开发
数学流程表示:
PWHAT→f(PWHAT)=SHOW→h(SHOW)=System P_{WHAT} \to f(P_{WHAT}) = S_{HOW} \to h(S_{HOW}) = System PWHAT→f(PWHAT)=SHOW→h(SHOW)=System
- PWHATP_{WHAT}PWHAT:业务需求 / 系统需求
- SHOWS_{HOW}SHOW:系统分析 + 架构与设计
- SystemSystemSystem:最终实现的系统
注意:在任何阶段混合 WHAT 和 HOW,都可能导致需求不明确、架构设计错误或开发失败。
C++ 示例(概念映射)
#include<iostream>#include<string>usingnamespace std;// WHAT 阶段: 定义系统需求structSystemRequirement{ string mustDo;// 系统必须做什么};// HOW 阶段: 定义系统实现方案structArchitecture{ string implementationDetails;// 系统如何实现};intmain(){// WHAT 阶段: 不涉及 HOW SystemRequirement req ={"处理用户数据并生成报告"};// HOW 阶段: 根据需求进行架构设计 Architecture arch; arch.implementationDetails ="使用多线程处理数据,生成PDF报告"; cout <<"Requirement: "<< req.mustDo << endl; cout <<"Architecture: "<< arch.implementationDetails << endl;return0;}注意:在 WHAT 阶段,不要写 arch.implementationDetails;在 HOW 阶段,不要重新定义 req.mustDo。
总结
- WHAT = 系统必须做什么(业务关注)
- HOW = 系统如何实现(技术关注)
- 绝不可混合
Mixing WHAT and HOW ⟹ Confusion, Misalignment, Project Risk \text{Mixing WHAT and HOW} \implies \text{Confusion, Misalignment, Project Risk} Mixing WHAT and HOW⟹Confusion, Misalignment, Project Risk
小心:过度规格化 (Be Wary: Overspecification)
过度规格化是指给系统添加了不必要或错误的约束,这会带来负面影响。
1. 什么是过度规格化 (Overspecification)
定义 (def):
- 过度规格化 = 错误约束 (Erroneous Constraint)
- 错误约束总是提供负面价值
特点:
- 指定不必要的细节 (Specify unnecessary detail)
- 例如在系统设计中规定一些行为或实现细节,但这些并非系统本质需要。
- 假设不必要的行为 (Assume unnecessary behavior)
- 将某些行为视为必要,但实际上不影响系统目的。
数学表示:
Overspecification=Constraint∖System Purpose Overspecification = \text{Constraint} \setminus \text{System Purpose} Overspecification=Constraint∖System Purpose
- 将某些行为视为必要,但实际上不影响系统目的。
- ∖\setminus∖ 表示与系统目标不相关的约束。
2. 为什么 Spiral / Agile 避免过度规格化?
- Spiral / Agile 方法倾向于 跳过或延迟过度规格化阶段
- 原因:过度规格化会 伤害系统和开发者
关键机制: - 不断回到“第一性原理 (First Principles)”
- 反复检查系统的 核心目的 (System Purpose)
- 任何与目的无关的假设都不是“真实”规格或约束
数学表示:
ValidSpec=Constraints c∣c directly supports System Purpose ValidSpec = {\text{Constraints } c | c \text{ directly supports System Purpose}} ValidSpec=Constraints c∣c directly supports System Purpose
Overspecification=Constraints c∣c∉ValidSpec Overspecification = {\text{Constraints } c | c \notin ValidSpec} Overspecification=Constraints c∣c∈/ValidSpec
3. Agile 的真正目标 (A Real Problem™ That Agile Does Really Solve™)
- Agile 运动的一个核心动机是 避免过度规格化
- 通过 迭代开发 和 持续验证假设,确保系统规格紧贴业务目标,而不是被无关约束束缚
C++ 示例(概念映射):
#include<iostream>#include<string>usingnamespace std;// 系统目的:生成报告structSystemPurpose{ string goal ="Generate accurate business reports";};// 错误约束:规定报告必须使用特定字体和颜色(不必要)structOverspecifiedConstraint{ string font ="Arial";// 不必要 string color ="Blue";// 不必要};intmain(){ SystemPurpose system; OverspecifiedConstraint constraint; cout <<"System Goal: "<< system.goal << endl; cout <<"Warning: Avoid overspecification like "<< constraint.font <<" font and "<< constraint.color <<" color"<< endl;}注意:真正有价值的规格只需要满足 SystemPurpose.goal,字体和颜色是过度规格化的例子。4. 核心总结
- 过度规格化 = 错误约束 = 负面价值
- 避免策略:
- 回到第一性原理:Purpose→ValidSpecPurpose \to ValidSpecPurpose→ValidSpec
- 使用迭代/Spiral/Agile 方法延迟细节决策
- 只指定与目的直接相关的约束
- 公式总结:
Overspecification=Constraints not required by PurposeValue(Overspecification)<0 Overspecification = {\text{Constraints not required by Purpose}} \\ Value(Overspecification) < 0 Overspecification=Constraints not required by PurposeValue(Overspecification)<0
ValidSpec=Constraints that support System PurposeValue(ValidSpec)>0 ValidSpec = {\text{Constraints that support System Purpose}} \\ Value(ValidSpec) > 0 ValidSpec=Constraints that support System PurposeValue(ValidSpec)>0
回顾:限制系统的术语 (Review: Terms To Limit Your System)
这些术语用于描述 系统交付中的“限制”,帮助开发者理解系统设计和实现的边界。
1. 需求 (Requirement)
定义 (def):
- 需求 = 被强制的规格 (A mandated specification)
- 系统必须满足的条件或功能
数学表示:
Requirement=Must-do constraints for the system Requirement = {\text{Must-do constraints for the system}} Requirement=Must-do constraints for the system
C++ 示例(需求概念):
#include<iostream>#include<string>usingnamespace std;// 系统需求structRequirement{ string description;// 必须完成的功能};intmain(){ Requirement req; req.description ="系统必须支持用户登录功能"; cout <<"Requirement: "<< req.description << endl;}2. 约束 (Constraint)
定义 (def):
- 约束 = 可能性的限制 (A limit of possibility)
- 描述系统实现、设计或运行中不可逾越的边界
数学表示:
Constraint=Limits on system design, implementation, or operation Constraint = {\text{Limits on system design, implementation, or operation}} Constraint=Limits on system design, implementation, or operation
C++ 示例(约束概念):
structConstraint{ string limit;// 限制条件};intmain(){ Constraint c; c.limit ="响应时间必须小于2秒";// 系统性能限制 cout <<"Constraint: "<< c.limit << endl;}3. 偏好 (Preference)
定义 (def):
- 偏好 = 排序备选方案的倾向 (An expressed bias to rank alternatives)
- 表示对某种实现方式或设计方案的倾向性选择,并非强制
数学表示:
Preference=Ranking or bias among alternatives Preference = {\text{Ranking or bias among alternatives}} Preference=Ranking or bias among alternatives
C++ 示例(偏好概念):
structPreference{ string preference;// 偏好描述};intmain(){ Preference p; p.preference ="优先使用C++17标准特性";// 开发团队偏好 cout <<"Preference: "<< p.preference << endl;}4. 能力 (Capability)
定义 (def):
- 能力 = 系统或团队交付某项功能的能力 (An ability to deliver)
- 描述实际可以实现或提供的功能,不是需求或偏好
数学表示:
Capability=Ability of system or team to deliver functionality Capability = {\text{Ability of system or team to deliver functionality}} Capability=Ability of system or team to deliver functionality
C++ 示例(能力概念):
structCapability{ string ability;// 能力描述};intmain(){ Capability cap; cap.ability ="系统可以同时处理1000个并发用户"; cout <<"Capability: "<< cap.ability << endl;}总结公式
这些术语在系统设计中形成不同层次的限制和指导:
SystemLimits=Requirement∪Constraint∪Preference∪Capability SystemLimits = Requirement \cup Constraint \cup Preference \cup Capability SystemLimits=Requirement∪Constraint∪Preference∪Capability
- RequirementRequirementRequirement → 必须满足
- ConstraintConstraintConstraint → 不可逾越
- PreferencePreferencePreference → 可选择的倾向
- CapabilityCapabilityCapability → 可实现的能力
理解这些概念有助于避免混淆 WHAT / HOW、避免过度规格化,同时指导合理的系统架构与设计。
理解你的系统限制 (Understand Your System-Limits)
过度规格化 (Overspecification) 是一种痛苦的限制,但它只是系统限制的一种。
作为架构师 (Architect),你需要在 多种限制之间平衡。
1. 需求限制 (Requirement Limit)
- 定义:你受制于 强制性规定,即系统必须做的功能或条件。
- 如何放宽 (How to relax):
- 协商需求或“验收标准 (Acceptance Criteria)”
- 判断哪些需求可以灵活处理
数学表示:
RequirementLimit=Mandated specifications for system RequirementLimit = {\text{Mandated specifications for system}} RequirementLimit=Mandated specifications for system
C++ 示例:
structRequirement{ std::string description;}; Requirement req; req.description ="系统必须支持用户登录功能";// 强制性要求// 放宽示例:协商更灵活的认证方式bool relaxedRequirement =true;2. 约束限制 (Constraint Limit)
- 定义:你受制于 技术或物理可能性 (limits of technology or physics)
- 如何放宽:
- 探索替代技术
- 重新设计以突破原有限制
数学表示:
ConstraintLimit=Limits of technology or physics ConstraintLimit = {\text{Limits of technology or physics}} ConstraintLimit=Limits of technology or physics
C++ 示例:
structConstraint{ std::string limit;}; Constraint c; c.limit ="响应时间必须小于2秒";// 技术约束// 放宽示例:使用更高效算法bool alternativeTech =true;3. 偏好限制 (Preference Limit)
- 定义:你受制于 偏好或权衡 (bias expressing preferred tradeoffs)
- 如何放宽:
- 协商不同的权重或偏好
- 优化决策顺序
数学表示:
PreferenceLimit=Preferred tradeoff rankings PreferenceLimit = {\text{Preferred tradeoff rankings}} PreferenceLimit=Preferred tradeoff rankings
C++ 示例:
structPreference{ std::string tradeoff;}; Preference p; p.tradeoff ="优先使用C++17特性";// 偏好限制// 放宽示例:协商使用C++14或其他标准bool relaxedPreference =true;4. 能力限制 (Capability Limit)
- 定义:你受制于 实现团队的能力 (what team can deliver)
- 如何放宽:
- 培训团队
- 调整团队组合
- 提供额外支持或工具
数学表示:
CapabilityLimit=Team availability and capabilities CapabilityLimit = {\text{Team availability and capabilities}} CapabilityLimit=Team availability and capabilities
C++ 示例:
structCapability{ std::string teamAbility;}; Capability team; team.teamAbility ="团队只能处理1000个并发用户";// 放宽示例:培训团队,或者增加成员bool enhancedCapability =true;5. 总结:架构师的多限制平衡
作为架构师,你需要平衡 Requirement, Constraint, Preference, Capability 四种限制:
SystemLimits=RequirementLimit∪ConstraintLimit∪PreferenceLimit∪CapabilityLimit SystemLimits = RequirementLimit \cup ConstraintLimit \cup PreferenceLimit \cup CapabilityLimit SystemLimits=RequirementLimit∪ConstraintLimit∪PreferenceLimit∪CapabilityLimit
- 放宽策略:
| 限制类型 | 放宽方式 |
|---|---|
| Requirement | 协商需求或改变验收标准 |
| Constraint | 探索替代技术或方案 |
| Preference | 协商权衡顺序或优先级 |
| Capability | 培训团队或调整团队组合 |
数学表示放宽操作:
Relax(Limit)={Negotiate,if Requirement or PreferenceExplore alternatives,if ConstraintTrain or reallocate team,if Capability Relax(Limit) = \begin{cases} \text{Negotiate}, & \text{if Requirement or Preference} \\ \text{Explore alternatives}, & \text{if Constraint} \\ \text{Train or reallocate team}, & \text{if Capability} \end{cases} Relax(Limit)=⎩⎨⎧Negotiate,Explore alternatives,Train or reallocate team,if Requirement or Preferenceif Constraintif Capability
C++ 开发看起来像什么 (Using C++ Looks Like…)
C++ 开发可以通过 抽象状态机 (Abstract State Machine, ASM) 来直接推理。开发者可以从 底层硬件 或 系统概念 两个方向进行开发。
1. 底向开发 (Bottom-Up)
开发者从 硬件 + C++保证 出发,逐步构建域类型、域算法、域子系统,最终形成系统。
流程:
- 定义域类型 (Domain Types)
- 从基础类型(如
int,double)定义领域相关类型 - 保证行为明确 (Well-Defined Behavior)
- 从基础类型(如
- 实现域算法 (Domain Logic / Algorithms)
- 基于域类型实现算法
- 实现域子系统 (Subsystems)
- 基于域算法构建子系统
数学表示:
BottomUp:Hardware→C++ GuaranteesDomainTypes→DomainAlgorithms→Subsystems→System \text{BottomUp}: Hardware \xrightarrow{\text{C++ Guarantees}} DomainTypes \xrightarrow{} DomainAlgorithms \xrightarrow{} Subsystems \xrightarrow{} System BottomUp:HardwareC++ GuaranteesDomainTypesDomainAlgorithmsSubsystemsSystem
C++ 示例(底向开发):
- 基于域算法构建子系统
#include<iostream>#include<vector>usingnamespace std;// Step 1: 定义域类型structTemperature{double value;};// Step 2: 实现域算法doubleaverageTemp(const vector<Temperature>& temps){double sum =0;for(auto t : temps) sum += t.value;return sum / temps.size();}// Step 3: 实现域子系统structWeatherStation{ vector<Temperature> readings;doublegetAverage(){returnaverageTemp(readings);}};intmain(){ WeatherStation station; station.readings ={{20.5},{22.0},{21.5}}; cout <<"Average temperature: "<< station.getAverage()<<" C"<< endl;}解释:开发从 基础类型 Temperature → 算法 averageTemp → 子系统 WeatherStation 构建系统。
2. 顶向开发 (Top-Down)
开发者从 系统概念 → 域子系统 → 域算法 → 域类型,逐步实现具体系统。
流程:
- 定义操作理论 (Theory of Operation)
- 描述系统行为、目标和约束
- 实现域子系统 (Domain Subsystems)
- 将理论映射为子系统
- 实现域算法 (Domain Algorithms)
- 子系统内部的算法实现
数学表示:
TopDown:SystemConcept→DomainSubsystems→DomainAlgorithms→DomainTypes→Hardware \text{TopDown}: SystemConcept \xrightarrow{} DomainSubsystems \xrightarrow{} DomainAlgorithms \xrightarrow{} DomainTypes \xrightarrow{} Hardware TopDown:SystemConceptDomainSubsystemsDomainAlgorithmsDomainTypesHardware
C++ 示例(顶向开发):
- 子系统内部的算法实现
#include<iostream>#include<vector>usingnamespace std;// Step 1: 系统操作理论// 系统目标: 获取平均温度并报警// Step 2: 实现域子系统structWeatherSubsystem{ vector<double> readings;doublegetAverage(){double sum =0;for(auto r : readings) sum += r;return sum / readings.size();}boolalarmIfTooHigh(){returngetAverage()>25.0;}};// Step 3: 实现域算法 (可进一步定义域类型)structTemperature{double value;};intmain(){ WeatherSubsystem ws; ws.readings ={22.0,24.5,26.0}; cout <<"Average temperature: "<< ws.getAverage()<<" C"<< endl; cout <<"Alarm: "<<(ws.alarmIfTooHigh()?"ON":"OFF")<< endl;}解释:开发从 系统概念 → 子系统 → 算法 → 域类型,逐步落实设计。
3. 总结比较
| 方法 | 出发点 | 流程 | 数学表示 |
|---|---|---|---|
| Bottom-Up | 硬件 + C++ 标准 | Domain Types → Domain Algorithms → Subsystems → System | Hardware→DomainTypes→DomainAlgorithms→Subsystems→SystemHardware \xrightarrow{} DomainTypes \xrightarrow{} DomainAlgorithms \xrightarrow{} Subsystems \xrightarrow{} SystemHardwareDomainTypesDomainAlgorithmsSubsystemsSystem |
| Top-Down | 系统概念 | System Concept → Domain Subsystems → Domain Algorithms → Domain Types → Hardware | SystemConcept→DomainSubsystems→DomainAlgorithms→DomainTypes→HardwareSystemConcept \xrightarrow{} DomainSubsystems \xrightarrow{} DomainAlgorithms \xrightarrow{} DomainTypes \xrightarrow{} HardwareSystemConceptDomainSubsystemsDomainAlgorithmsDomainTypesHardware |
- Bottom-Up 优势:更易保证类型安全和行为明确
- Top-Down 优势:更易对齐系统目标和操作理论
开发轴 (Development Axes) 与自由度 (Many Degrees Of Freedom)
- 系统开发包含许多自由度和选择
- 现实开发阶段 (Real-World Development Stages) 帮助我们理解 应该期待什么,以及 每个阶段的目标和输出
1. 系统分析 (System Analysis)
核心问题:我们要构建什么系统?
- 目标:
- 确定业务需求
- 明确系统功能
- 回答“我们为什么被雇佣?”
数学表示:
SystemAnalysis:Identify Requirements,Constraints,Capabilities,Preferences SystemAnalysis: \text{Identify } {Requirements, Constraints, Capabilities, Preferences} SystemAnalysis:Identify Requirements,Constraints,Capabilities,Preferences
C++ 概念示例:
structSystemRequirement{ std::string description;}; std::vector<SystemRequirement>analyzeSystem(){return{{"支持用户登录"},{"生成报告"},{"高并发处理"}};}输出:一组需求集合,作为后续设计和开发的基础。
2. 概念化 (Conceptualize / Theory of Operation)
目标:定义系统的操作理论 (Theory of Operation),区分要构建的系统与不构建的系统
- 可行性 (Feasibility):
- 技术问题必须在系统理解前被回答
- 通过 原型 (Prototype) 验证系统是否可行
数学表示:
Feasibility=Check if system can be built given technology and constraints Feasibility = \text{Check if system can be built given technology and constraints} Feasibility=Check if system can be built given technology and constraints
C++ 概念示例(原型验证):
structPrototype{bool works;}; Prototype testPrototype(){ Prototype p; p.works =true;// 假设我们测试核心功能可行return p;}// 如果原型不可行,回到概念化阶段if(!testPrototype().works){// 重新设计概念}- 注意:原型可以与可行性阶段合并,如果已有类似系统或技术,可跳过。
3. 开发阶段 (Development / Build It!)
- 任务:
- 实现操作理论 (Implement Theory of Operation)
- 编码/实现设计 (Code / Implement Design)
- 验证 (Validate):确保需求被满足,技术行为正确
数学表示:
Development=Implement(SystemConcept)→CodeSubsystems→ValidateSystem Development = Implement(SystemConcept) \xrightarrow{Code} Subsystems \xrightarrow{Validate} System Development=Implement(SystemConcept)CodeSubsystemsValidateSystem
C++ 概念示例:
structSubsystem{voidrun(){// 具体实现系统功能 std::cout <<"Subsystem running..."<< std::endl;}}; Subsystem s; s.run();4. 部署阶段 (Deploy)
- 任务:
- 交付系统给生产或客户
- 更新文档
- 培训支持人员
- 系统可用性交付
数学表示:
Deploy(System)=Make system available to end-users Deploy(System) = \text{Make system available to end-users} Deploy(System)=Make system available to end-users
5. 迭代与反馈 (Feedback Loop)
- 后期阶段的反馈可以反向影响早期阶段
- 这与 Spiral / Agile 方法类似,形成循环迭代
数学表示:
Feedback:LaterPhase→EarlierPhase Feedback: LaterPhase \rightarrow EarlierPhase Feedback:LaterPhase→EarlierPhase
C++ 概念示例:
voidfeedbackLoop(SystemRequirement &req,bool userSatisfied){if(!userSatisfied){// 迭代修改需求 req.description +=" (更新需求)";}}6. 总结流程 (Real-World Development Flow)
数学化流程表示:
$$
- SystemAnalysis \to 2. Conceptualize/Feasibility \xrightarrow{Prototype} 3. Development/Implementation \to 4. Deploy \xrightarrow{Feedback} 1
$$
- System Analysis:定义要构建什么
- Conceptualize / Feasibility:定义操作理论、验证可行性
- Development:实现理论和设计
- Deploy:交付系统
- Feedback:后期反馈指导早期调整
1. 唯一的“硬障碍” (The Only “Hard Barrier”)
- 架构师必须在考虑“闪亮的新技术 (sparkly new things)”时保持理智,扮演“成年人”角色。
- 绝不能将可行性 (Feasibility) 阶段直接放大成开发 (Development) 阶段,否则会带来严重问题:
- 成本大幅增加
- 在未经验证的实验上投入生产级资源
- 风险放大
- 部署级问题可能造成严重影响
- 质量下降,开发者困惑
- 实验与生产混合,导致低标准实验与高标准生产混乱
数学表示:
HardBarrierViolation ⟹ Cost↑Risk↑Quality↓ \text{HardBarrierViolation} \implies \text{Cost} \uparrow \text{Risk} \uparrow \text{Quality} \downarrow HardBarrierViolation⟹Cost↑Risk↑Quality↓
C++ 示例(错误做法,原型直接升到生产级别):
// 错误做法: 将实验性算法直接部署到生产intexperimentalAlgorithm(int x){return x * x;// 未测试边界情况}intmain(){int result =experimentalAlgorithm(1000000);// 可能溢出}2. 并行与概念进展 (Parallel & Concept Progression)
- 并行进展 (Parallel Progression)
- 不同阶段可“同时进行”,例如 Feasibility、Conceptualization、Development
- 概念进展 (Concept Progression)
- 随阶段演化:
- Requirements → Conceptualization → Development
- 允许响应意外:
- 关键客户改变需求
- 目标用例改变
- 业务方向改变
- 随阶段演化:
- 开发进展 (Development Progression)
- 随阶段演化:
- Feasibility / Prototyping → Development → Productization
- 意外情况:
- 迁移新平台/操作系统
- 迁移新编译器/工具链
- 更换或添加第三方子系统
- 可能原因:
- 快速变化市场
- 收购、兼并或合并
- 随阶段演化:
3. 两种开发模型 (Two Development Models)
- 正式开发 (Formal / Waterfall Model)
- 顺序阶段:需求分析 → 设计 → 实现 → 测试 → 部署
- 迭代开发 (Iterative / Spiral / Agile Model)
- 通过原型、反馈循环不断调整需求和设计
- 允许更灵活应对市场变化
数学表示:
Waterfall: Requirements→Design→Implementation→Verification→Deployment \text{Waterfall: } Requirements \to Design \to Implementation \to Verification \to Deployment Waterfall: Requirements→Design→Implementation→Verification→Deployment
Spiral/Agile: IterativeCycle(Requirements,Design,Implementation,Feedback) \text{Spiral/Agile: } IterativeCycle(Requirements, Design, Implementation, Feedback) Spiral/Agile: IterativeCycle(Requirements,Design,Implementation,Feedback)
4. 开发空间 (Development Space)
开发空间描述 开发过程中的状态与知识水平:
| 阶段 | 我们知道什么 | 状态 |
|---|---|---|
| Conceptualization | 系统要构建什么 | We Know Exactly |
| Haven’t Started | 我们完全不清楚 | We Have No Idea |
| Development | 构建过程如何 | Started |
| Done | 系统完成 | We’re Done |
- 问题:在尚未开始或开发阶段,团队不确定如何操作
- Spiral / Agile 的做法:通过迭代减少未知
- Waterfall 的做法:严格按阶段执行
5. 架构空间 (Architectural Space)
架构空间描述 系统架构决策与业务需求对齐的状态:
| 阶段 | 核心参与者 | 关注点 |
|---|---|---|
| Conceptualization | Architects, Designers | 必须构思系统概念 |
| Haven’t Started | Architects, Designers | 理解潜在和实际权衡 |
| Development Started | Developers | 实现设计 |
| Done | Architects, Designers, Business Managers | 系统完成并满足目标客户需求 |
- 目标客户 (Target Customer):
- 系统需求和期望可能多维、多目标
- 架构师和设计师需要处理短期和长期目标,以及市场定位
数学表示:
DevelopmentSpace:Conceptualization→Development→Done DevelopmentSpace: Conceptualization \to Development \to Done DevelopmentSpace:Conceptualization→Development→Done
ArchitecturalSpace:Conceptualization→Architects,DesignersDevelopment→DevelopersDone ArchitecturalSpace: Conceptualization \xrightarrow{Architects, Designers} Development \xrightarrow{Developers} Done ArchitecturalSpace:ConceptualizationArchitects,DesignersDevelopmentDevelopersDone
6. 谁在每条轴上? (Who is found on each axis?)
| 轴 | 参与者 | 责任 |
|---|---|---|
| Conceptualization | Architects | 构思系统概念 |
| Conceptualization | Designers | 理解概念,提出设计方案 |
| Haven’t Started | Architects | 理解潜在和实际权衡 |
| Haven’t Started | Business Managers | 定义市场定位、战略目标 |
| Development Started | Developers | 实现系统 |
| Done | Architects, Designers, Business Managers | 系统完成,满足客户需求 |
核心思想:开发空间和架构空间是多维度的,每个角色在不同阶段承担不同责任,架构师必须控制“硬障碍”,保持可行性与风险的平衡。
7. 总结:开发 vs 架构空间
- 开发空间 (Development Space):
- 聚焦 构建过程与状态
- 角色:开发者、架构师、设计师
- 架构空间 (Architectural Space):
- 聚焦 概念设计、权衡、业务需求
- 角色:架构师、设计师、业务管理者
- 两者相互依赖:
- 开发空间提供实现反馈
- 架构空间提供设计决策和业务指导
1. 产品线复用动机 (Motivation for Reuse)
- 产品 (Product):可交付的单元
- 产品线 (Product Line):一组相关但独特的产品
- 产品族 (Product Family):一组相关但独特的产品线
随着产品种类或目标客户的增加,复用动机也增加。
- 市场差距分析 (Market Gap Analysis):
- 每个“相关但独特”的产品都鼓励某种架构复用
- 通过分析市场中所有产品族位置,确定哪些可以复用
数学表示:
ReuseMotivation∝Variations in Product Offerings ReuseMotivation \propto \text{Variations in Product Offerings} ReuseMotivation∝Variations in Product Offerings
C++ 概念示例:
structProduct{ std::string name; std::string version;};structProductLine{ std::vector<Product> products;};structProductFamily{ std::vector<ProductLine> productLines;};2. 架构空间中的物理维度 (Physical Dimensions in Architectural Space)
- 复用等级 (Levels of Reuse):
| 复用程度 | 范围 |
|---|---|
| 少 (Less Reuse) | 仅应用于特定应用 |
| 可复用 | 产品线内部 |
| 可复用 | 产品族内部 |
| 可复用 | 企业内部 |
| 多 (More Reuse) | 第三方可复用 |
- 复用相关考虑事项:
- 用户界面 (UI)
- 子系统配置 (Subsystem Configuration)
- 系统配置 (System Configuration)
- 业务逻辑不变量 (Business Logic Invariants):
- 类型 (Types)
- 处理模型 (Processing Models)
- 控制流 (Control Flows)
- 数据流 (Data Flows)
- 可维护性 / 支持接口 (Serviceability / Support Interfaces)
- 域特定数据处理 (Domain-Specific Data Handling)
- 日志 (Logging)
- 序列化 (Serialization)
- RPC / 分布式处理模型 (RPC, Distributed processing)
数学化表示复用空间:
ReuseLevel:Application,ProductLine,ProductFamily,Enterprise,ThirdParty ReuseLevel: { Application, ProductLine, ProductFamily, Enterprise, ThirdParty } ReuseLevel:Application,ProductLine,ProductFamily,Enterprise,ThirdParty
C++ 示例(复用代码模块):
// 可复用于整个产品族的数学库namespace ReusableMath {doubleadd(double a,double b){return a + b;}doublemultiply(double a,double b){return a * b;}}// 产品线内部复用structProductLineModule{voidprocess(){/* 处理业务逻辑 */}};3. 复用的成本与收益 (Cost and Benefits of Reuse)
正面效果 (Good):
- 促进一致性
- 所有开发者都知道“统一工作方式”
- 低成本创建新系统,提供规模经济
- 对安全和维护有益
- 库更新后,每个开发者均可获益
负面效果 (Bad):
- 库更新后,每个开发者均可获益
- 强制同一解决方案应用于不同问题
- 减少创新
- 可能减慢开发进度
- 库更新可能导致所有系统等待
- 增加耦合度,提高复杂性、时间和风险
- 无法单独在某个系统中快速修复
数学表示复用权衡:
TotalCost=f(Consistency,Maintainability)−g(Innovation,Flexibility) TotalCost = f(Consistency, Maintainability) - g(Innovation, Flexibility) TotalCost=f(Consistency,Maintainability)−g(Innovation,Flexibility)
4. 谁关心复用? (Who Cares About Reuse?)
| 角色 | 关注点 |
|---|---|
| 管理者 (Managers) | 一致性和优先级排名 |
| 安全专家 (Security Professionals) | 库更新后的安全 |
| 第三方 (3rd Parties) | 可用性和接口一致性 |
| 创新者 (Innovators) | 灵活性和创新 |
| 大公司 (Big Companies) | 成本降低和规模经济 |
| 支持工程师 (Support Engineers) | 可维护性 |
核心思想:复用提供一致性和成本优势,但增加耦合和约束,需要在创新、成本、维护性之间平衡。
5. 总结:复用战略 (Reuse Strategy)
- 动机:产品/产品线/产品族数量越多,复用价值越高
- 复用等级:从应用级 → 产品线 → 产品族 → 企业 → 第三方
- 关键权衡:
- 正面:一致性、降低新系统成本、规模经济
- 负面:降低创新、增加耦合、维护复杂性
- 决策者:架构师、管理者、开发者、安全专家、支持工程师等
数学总结:
ReuseDecision=argmaxReuseLevel(Consistency+CostSavings)−(InnovationLoss+Risk) \text{ReuseDecision} = \arg\max_{ReuseLevel} (Consistency + CostSavings) - (InnovationLoss + Risk) ReuseDecision=argReuseLevelmax(Consistency+CostSavings)−(InnovationLoss+Risk)