让我们想象一下,我们是一家汽车开发软件公司,我们拥有以下汽车公司的初始设计。
软件的初始设计
我们实现了汽车的所有功能,如燃料、发动机、轮胎和车灯等。
后来,董事会决定实现新功能“自动换挡”,这是市场上极具需求的功能,并要求经理们在一周内实现它并提供演示。
经理们将此任务分配给其中一位开发人员来实现“自动换挡”功能。开发人员表示,我是一个面向对象的程序员,我将在一个小时内实现这个功能,并提供以下设计。
自动换挡的初始实现:
经理在董事会成员面前开始演示,他们惊讶地发现“Ambassador”和“Alto”拥有“自动换挡”功能,他们决定我们负担不起这些车的这个功能,并要求经理在这些车中删除自动换挡功能。
经理要求开发人员在“Ambassador”和“Alto”车中删除“自动换挡”功能。开发人员在思考如何在“Ambassador”和“Alto”车中删除“自动换挡”功能,由于他是一个面向对象的程序员,“覆盖isAutoGear()方法”将解决这个问题。
在这个实现过程中,董事会成员决定在不同的汽车中实现“不同类型的发动机”。当发动机不同时,自动“燃料也不同”,并要求经理和开发人员在软件中实现相同的功能。
开发人员发现规格在每个董事会会议上都在变化,于是他提出了以下设计。
接口设计
开发人员将此设计提交给经理进行审查。经理问开发人员,“这是实现我们规格的完美设计吗?”
“你对此有何想法......以上设计有什么缺点吗?”
以上设计的缺点
想象一下,未来我们有100种汽车类型而不是4种,我们需要在每个类中覆盖引擎、齿轮和燃料接口方法,这会导致
- 子类之间的重复代码
- 如果某些内容发生变化,我们需要在每个类中进行更改,很容易出现问题。
- 维护代码非常困难
- 很难获得关于汽车行为和运行时更改的知识。
策略模式
后来,开发人员进行头脑风暴,观察了哪些规格经常变化和它们的行为,他还观察了汽车中哪些规格不会改变,并制作了如下列表:
-
已更改的规格:
-
发动机
-
燃料
-
齿轮
-
未更改的规格:
-
轮胎
-
车灯
他将已更改的规格封装在Car类中,并制作了最终的设计。
策略模式设计
“观察类的行为并封装经常变化的内容。这种模式被称为策略模式。”
面向对象的基础知识
- 抽象
- 封装
- 多态
- 继承
我们在此模式中遵循的面向对象原则
- 封装变化
- 优先使用组合而不是继承
- 面向接口编程,而不是面向实现编程
评论(0)