记录–卸下if-else 侠的皮衣!- 策略模式

  • 记录–卸下if-else 侠的皮衣!- 策略模式已关闭评论
  • 176 次浏览
  • A+
所属分类:Web前端
摘要

给我一个功能,我总是要写很多if-else,虽然能跑,但是维护起来确实很难受,每次都要在一个方法里面增加逻辑,生怕搞错,要是涉及到支付功能,分分钟炸锅


这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

记录--卸下if-else 侠的皮衣!- 策略模式

?当我是if-else侠的时候

?怕出错

给我一个功能,我总是要写很多if-else,虽然能跑,但是维护起来确实很难受,每次都要在一个方法里面增加逻辑,生怕搞错,要是涉及到支付功能,分分钟炸锅

?难调试

我总是不知道之前写的逻辑在哪里,一个方法几百行逻辑,而且是不同功能点冗余在一起!这可能让我牺牲大量时间在这查找调试中

?交接容易挨打

当你交接给新同事的时候,这个要做好新同事的白眼和嘲讽,这代码简直是坨翔!这代码简直是个易碎的玻璃,一碰就碎!这代码简直是个世界十大奇迹!

?脱下if-else侠的皮衣

先学习下开发的设计原则

单一职责原则(SRP)

就一个类而言,应该仅有一个引起他变化的原因

开放封闭原则(ASD)

类、模块、函数等等应该是可以扩展的,但是不可以修改的

里氏替换原则(LSP)

所有引用基类的地方必须透明地使用其子类的对象

依赖倒置原则(DIP)

高层模块不应该依赖底层模块

迪米特原则(LOD)

一个软件实体应当尽可能的少与其他实体发生相互作用

接口隔离原则(ISP)

一个类对另一个类的依赖应该建立在最小的接口上

在学习下设计模式

大致可以分三大类:创建型结构型行为型
创建型:工厂模式 ,单例模式,原型模式
结构型:装饰器模式,适配器模式,代理模式
行为型:策略模式,状态模式,观察者模式

为了尽快脱掉这个if-else的皮衣,我们就先学习一种比较容易接受的设计模型:策略模式

策略模式

举个例子

  • 当购物类型为“苹果”时,满 100 - 20,不满 100 打 9 折
  • 当购物类型为“香蕉”时,满 100 - 30,不满 100 打 8 折
  • 当购物类型为“葡萄”时,满 200 - 50,不叠加
  • 当购物类型为“梨”时,直接打 5 折
    然后你根据传入的类型和金额,写一个通用逻辑出来, 当我是if-else侠的时候,我估计会这样写:

funcion getPrice(type,money)   //处理苹果    if(type == 'apple'){      if(money >= 100){        return money - 20      }      return money * 0.9    }   //处理香蕉     if(type == 'banana'){      if(money >= 100){        return money - 30      }      return money * 0.8    }   //处理葡萄     if(type == 'grape'){      if(money >= 200){        return money - 50      }      return money    }   //处理梨     if(type == 'pear'){        return money * 0.5    } }

然后我们开始来分析问题:

  1. 违反了单一职责原则(SRP)
    一个方法里面处理了四个逻辑,要是里面的哪个代码块出事了,调试起来也麻烦
  2. 违反了开放封闭原则(ASD)
    假如我们要增加多一种水果的逻辑,就又要在这个方法中修改,然后你修改完这个方法,就跟测试说,我在这个方法增加了多一个种水果,可能要重新回归这个方法,那你看测试增加了多少工作量

改造考虑:消灭if-else, 支持扩展但是不影响原本功能!

const fruitsPrice = {   apple(money){    if(money >= 100){        return money - 20      }      return money * 0.9   },   banana(money){       if(money >= 100){        return money - 30      }      return money * 0.8   },   grape(money){    if(money >= 200){        return money - 50      }      return money   },   pear(money){    return money * 0.5   } }

首先定义一个fruitPrice对象,里面都是各种水果价格的映射关系
然后我们调用的时候可以这样

function getPrice(type,money){   return fruitsPrice[type](money) }

当我们要扩展新水果的时候

fruitsPrice.orange = function(money){    return money*0.4 }

综上所述: 用策略模式重构这个原本的逻辑,方便扩展,调试,清晰简明,当然这只是一个模式重构的情况,可能还有更优的情况,靠大家摸索

本文转载于:

https://juejin.cn/post/7239267216805871671

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 记录--卸下if-else 侠的皮衣!- 策略模式