上一章节我们有简单的在提一下软件架构设计的两个基本原则 :
这里我们在提一次。然後接下来我们这篇文章将要来谈谈 SOLID 中的 OCP 开发一封闭原则,也是为了达成上面这两件原则。
根据 《 Clean Architecture 》这本书里所书写的定义为 :
一个软件应该对於扩展是开放的,但对於修改是封闭的
这个比较白话文的来说我觉得是 :
当有新功能时,是可以用类式 plugin 的方式加新功能,而不是去修改原本的程序
这个违反这个原则,事实上在我们写的程序码中非常的常见,你想想 ~ 是不是在程序中,有很多 function 里会使用 if else 情境来判断要用什麽来处理,例如订单可能会根据不同产品来进行一些对同处理,这时我们是不是最直觉的写法就是加个 if 呢 ?
我个人是认为在开发初起,我们很难预测未来的变动,所以这时简单用个 if 来处理,就我个人是觉得可以接受,但是如果之後又来 ~ 那我就觉得真的可能考虑重构了呢。
这里只要记好一件事情 :
开放封闭原则在软件架构存在的目的,就是在於怕你要改时,会动到原本的程序码,而导致可能的出错
但我小声的说…如果有写测试,那事实上不太会影响…… 在某些小型专案上。
但是这个如果拉到大型专案上,一直用 if else 又或是一直在原本的地方加功能,会哭的不是你,而是後人,活生生的血泪屎。
首先来来个基本版,就是一个专门用来处理订单的类别,然後他有个方法可以计算这个订单的费用。
// bad
class OrderFeeCalculator{
constructor(order){
this.order = order
}
calcFee(){
let fee = 0
fee = 0.1 * this.order.price
return fee
}
}
然後这时有个新需求,我们订单的类型为『 文章 ARTICLE 』的话,则费用只要价格的 5% 就好,那这时通常第一直觉会直接改成如下 :
// Bad 2
class OrderFeeCalculator{
constructor(order){
this.order = order
}
calcFee(){
let fee = 0
if(this.order.category === 'ARTICLE'){
fee = 0.05 * this.order.price
}else{
fee = 0.1 * this.order.price
}
return fee
}
}
这一题事实上可以用一些设计模式来解决。
这样如果某一个产品需要特殊的计算,那就只要在对应的 strategy 里修改运算就 ok 罗,而不用怕会影响到其它产品的运算。
// Good
class OrderFeeCalculator{
constructor(order){
this.order = order
}
calcFee(){
let fee = 0
fee = _productFeeStrategyFactory[this.order.category].calcFee(this.order)
return fee
}
_productOrderFeeFactor(category){
switch (category) {
case 'ARTICLE':
return new ArticleFeeStrategy()
case 'COURSE':
return new CorseFeeStrategy()
}
}
}
class ArticleFeeStrategy{
calcFee(order){
return this.order.price * 0.05
}
}
class CorseFeeStrategy{
calcFee(order){
return this.order.price * 0.1
}
}
事实上我仔细想想,不少的设计模式都是为了来达到『 开放封闭原则 』,例如 :
老样子,来问一下三个问题,来加深记忆
我觉得分层架构也有一定原因是因为这个原则而产生的,我们不希望 Presenters 层级的修改,影响到 Controller。
分层架构、与一些设计模式都有连结,这些都是可以让我们们更接近 OCP 的方法。
<<: Day 17:「我们,是好朋友哦~」- Vue 简介
前四天我们经历一番折腾, 终於把 Octopus Deploy 架起来, 从 Octopus Dep...
在介绍的时候有说到我是在爬文苹果电脑的时候注意到ARM的!不得不说,使用了两个多月下来,对於使用全新...
前言 阵列是一种资料结构,里面装载的资料必须是同性质的,不能同时装载着字串又装载着整数,且建立後阵列...
全民疯AI系列2.0完赛总结 不知不觉就参加了三届iT邦铁人赛,很高兴能够藉由此活动分享经验与知识。...
Day32 写在Go繁之後 这是我的第0010 0000篇文章。 为什麽系列标题要叫做Go繁不及备载...