在业务需求变动的时候可能需要修改方法,修改的时候需要考虑如何降低方法参数的学习成本和怎么才能让方法更加通用。下面代码是用来刷新属性面板的脚本:
--属性值由等级,星级决定 例如:hp = 星级 * 1.5 + 等级 * 2
function M:updateBaseAttributes(hero, copy_hero)
--更新属性面板
--设置头像 属性 名字 提升 ...
--用高一级的copy_hero来计算提升的数值
end
--- up_key 支持 [星级, 等级]
function M:updateUIByType(hero, up_key) -- 可添加up_value
--复制一份对象
local copy_hero = Global:copyHero(hero)
--将属性值设置为高一级
copy_hero:setValue(up_key, copy_hero:getValue(up_key) + 1) -- 1改为(up_value or 1)
--更新UI
self:updateBaseAttributes(hero, copy_hero)
end
原本的使用场景是刷新属性面板,从原有的对象中拷贝一个出来,用两个对象来计算差值,体现升1级后的提升。但是之后出现新的需求,要体现连升几级后的提升。那么这个需求在原有的基础上改很简单,只需要添加一个参数up_value就能自定义提升的等级,原本就有一个key作为参数,多一个value作为参数并不会增加学习成本。
但此时又增加了一个需求,需要体现指定等级从A到B体现提升,如果将up_value改为valueA,valueB函数的学习成本就会增加很多:
--- up_key 支持 [星级, 等级]
function M:updateUIByType(hero, up_key, valueA, valueB)
--复制一份对象A
local copy_heroA = Global:copyHero(hero)
--复制一份对象B
local copy_heroB = Global:copyHero(hero)
--将A属性值设置为valueA
copy_heroA:setValue(up_key, valueA)
--将B属性值设置为valueB
copy_heroB:setValue(up_key, valueB)
--更新UI
self:updateBaseAttributes(copy_heroA, copy_heroB)
end
valueA和valueB这两个参数是强关联的,所以即使第一个需求用到这个函数也需要额外传入两个参数,原本2个参数就能使用现在变为4个参数,这会让使用者感到困惑。
这个脚本的职责只是为了刷新UI,表现升级前后两者的差异,那么就应该将参数定义成两个对象,对象的拷贝和赋值不是这个脚本需要关心的逻辑,违背了单一职责的原则,所以应该修改为:
--copy_heroA 和 copy_heroB 都由调用者进行拷贝和赋值
function M:updateUIWithAdvance(copy_heroA, copy_heroB)
--更新UI
self:updateBaseAttributes(copy_heroA, copy_heroB)
end
这样定义的好处是,后续对象即使新增觉醒或者爆发之类的词条,甚至是bool类型的key值这个方法也能照收不误。虽然这样使用者在调用时需要写更多的逻辑,可能使用起来不方便,但上述情况两三行的逻辑属于可控的范围,如果将这些逻辑整合到方法中会让方法更难懂,逻辑更难处理,扩大它的职责范围,所以修改需要视情况而定,学会变通。