什么才是优秀的软件架构?
开始学习设计模式前,我们先来看看软件架构的设计过程,及需要达成的目标和尽量避免的陷阱。
其中,代码复用是减少开发成本最常用的方式之一,其目的非常明显,即:与其反复从头开发,不如在新对象中重用已有的代码。
这个想法表面看起来很棒,但实际上要让已有的代码在全新的代码中工作,还是需要付出额外努力的。组件间紧密的耦合、对具体类而非接口的依赖和硬编码的行为都会降低代码的灵活性,使得复用这些代码变得更加困难。
使用设计模式是增加软件组件灵活性并使其易于复用的方式之一。但是,这可能也会让组件变得更加复杂。
一般情况下,复用可以分为三个层次。在最底层,可以复用类、类库、容器,也许还有一些类的“团体(例如容器和迭代器)”。
框架位于最高层。它们能帮助你精简自己的设计,可以明确解决问题所需的抽象概念,然后用类来表示这些概念并定义其关系。例如,JUnit 是一个小型框架,也是框架的“Hello, world”,其中定义了 Test、TestCase 和 TestSuite 这几个类及其关系。框架通常比单个类的颗粒度要大。你可以通过在某处构建子类来与框架建立联系。这些子类信奉“别给我们打电话,我们会给你打电话的。”
还有一个中间层次。这是我觉得设计模式所处的位置。设计模式比框架更小且更抽象。它们实际上是对一组类的关系及其互动方式的描述。当你从类转向模式,并最终到达框架的过程中,复用程度会不断增加。
中间层次的优点在于模式提供的复用方式要比框架的风险小。创建框架是一项投入重大且风险很高的工作,模式则能让你独立于具体代码来复用设计思想和理念。
每个软件开发者都经历过许多相似的故事,导致它们发生的原因也不少。
首先,在完成了第一版的程序后,我们就应该做好了从头开始优化重写代码的准备,因为现在你已经能在很多方面更好的理解问题了,同时在专业水平上也有所提高,所以之前的代码现在看上去可能会显得很糟糕。
其次,可能是在你掌控之外的某些事情发生了变化,这也是导致许多开发团队转变最初想法的原因。比如,每位在网络应用中使用 Flash 的开发者都必须重新开发或移植代码,因为不断地有浏览器停止对 Flash 格式地支持。
最后,可能是需求的改变,之前你的客户对当前版本的程序感到满意,但是现在希望对程序进行 11 个“小小”的改动,使其可完成原始计划阶段中完全没有提到的功能,新增或改变功能。
当然这也有好的一面,如果有人要求你对程序进行修改,至少说明还有人关心它。因此在设计程序架构时,有经验的开发者都会尽量选择支持未来任何可能变更的方式。
代码复用
无论是开发哪种软件产品,成本和时间都是最重要的。较少的开发时间意味着可以比竞争对手更早进入市场。较低的开发成本意味着能够留出更多的营销资金,覆盖更广泛的潜在客户。其中,代码复用是减少开发成本最常用的方式之一,其目的非常明显,即:与其反复从头开发,不如在新对象中重用已有的代码。
这个想法表面看起来很棒,但实际上要让已有的代码在全新的代码中工作,还是需要付出额外努力的。组件间紧密的耦合、对具体类而非接口的依赖和硬编码的行为都会降低代码的灵活性,使得复用这些代码变得更加困难。
使用设计模式是增加软件组件灵活性并使其易于复用的方式之一。但是,这可能也会让组件变得更加复杂。
一般情况下,复用可以分为三个层次。在最底层,可以复用类、类库、容器,也许还有一些类的“团体(例如容器和迭代器)”。
框架位于最高层。它们能帮助你精简自己的设计,可以明确解决问题所需的抽象概念,然后用类来表示这些概念并定义其关系。例如,JUnit 是一个小型框架,也是框架的“Hello, world”,其中定义了 Test、TestCase 和 TestSuite 这几个类及其关系。框架通常比单个类的颗粒度要大。你可以通过在某处构建子类来与框架建立联系。这些子类信奉“别给我们打电话,我们会给你打电话的。”
还有一个中间层次。这是我觉得设计模式所处的位置。设计模式比框架更小且更抽象。它们实际上是对一组类的关系及其互动方式的描述。当你从类转向模式,并最终到达框架的过程中,复用程度会不断增加。
中间层次的优点在于模式提供的复用方式要比框架的风险小。创建框架是一项投入重大且风险很高的工作,模式则能让你独立于具体代码来复用设计思想和理念。
扩展性
需求变化是程序员生命中唯一不变的事情。比如以下几种场景:- 你在 Windows 平台上发布了一款游戏,现在人们想要 Mac OS 的版本。
- 你创建了一个使用方形按钮的 GUI 框架,但几个月后开始流行原型按钮。
- 你设计了一款优秀的电子商务网站,但仅仅几个月后,客户就要求新增电话订单的功能。
每个软件开发者都经历过许多相似的故事,导致它们发生的原因也不少。
首先,在完成了第一版的程序后,我们就应该做好了从头开始优化重写代码的准备,因为现在你已经能在很多方面更好的理解问题了,同时在专业水平上也有所提高,所以之前的代码现在看上去可能会显得很糟糕。
其次,可能是在你掌控之外的某些事情发生了变化,这也是导致许多开发团队转变最初想法的原因。比如,每位在网络应用中使用 Flash 的开发者都必须重新开发或移植代码,因为不断地有浏览器停止对 Flash 格式地支持。
最后,可能是需求的改变,之前你的客户对当前版本的程序感到满意,但是现在希望对程序进行 11 个“小小”的改动,使其可完成原始计划阶段中完全没有提到的功能,新增或改变功能。
当然这也有好的一面,如果有人要求你对程序进行修改,至少说明还有人关心它。因此在设计程序架构时,有经验的开发者都会尽量选择支持未来任何可能变更的方式。
所有教程
- C语言入门
- C语言编译器
- C语言项目案例
- 数据结构
- C++
- STL
- C++11
- socket
- GCC
- GDB
- Makefile
- OpenCV
- Qt教程
- Unity 3D
- UE4
- 游戏引擎
- Python
- Python并发编程
- TensorFlow
- Django
- NumPy
- Linux
- Shell
- Java教程
- 设计模式
- Java Swing
- Servlet
- JSP教程
- Struts2
- Maven
- Spring
- Spring MVC
- Spring Boot
- Spring Cloud
- Hibernate
- Mybatis
- MySQL教程
- MySQL函数
- NoSQL
- Redis
- MongoDB
- HBase
- Go语言
- C#
- MATLAB
- JavaScript
- Bootstrap
- HTML
- CSS教程
- PHP
- 汇编语言
- TCP/IP
- vi命令
- Android教程
- 区块链
- Docker
- 大数据
- 云计算