[问题] 在流程中插入检查或不检查 程式怎么写

楼主: saladim (杀拉顶)   2023-10-30 00:25:40
有遇到一个程式流程中 某些步骤可能要检查或不检查的问题 想请问该
怎么写比较好. 语言是使用C++
首先我有一个computing class, 里面有个member function,
专门负责做计算的动作 而里面有七个步骤:
class Engine::compute(...arguments...)
1. compute1
2. compute2
3. if checking fails this return pre-condition is not satisfied
4. compute3
5. foreach cofig in allowed_user_configurations
6 if checking succeed then store this configuration
7. return allowed_configuration
步骤3)跟步骤6)的检查是由一个complianceChecker的class来做的:
bool compliance.check(....arguments....)
现在呢 为了一些原因 提供了一个选项 可以让步骤3.)跟步骤6.)的检查不做-也就是
永远检查成功, 请问要怎么在不动到主流程的状况下, 来达成这件事情呢?
因为这边是简化版本 但其实检查的地方大概十多处....
全部都加if-else好像不是太好 如果考虑到未来在其他部分需要加检查 或是未来
流程异动 这样if-else很容易漏掉 或是忘记要加if-else
目前我的想法是 加一个wrapper class在compliance checker上 ctor吃一个要不要
做检查的boolean, 然后有一个perfect forwarding的 member function取代掉
原本的 compliance checker的check function(转call):
class wrapper {
public:
wrapper(bool doCheckIn): doCheck(doCheckIn) {}
template <typename ... Args>
bool check(Args&& ... args){
return !doCheck || checker.check(std::forward<Args>(args) ... );
}
private:
compliance checker
bool doCheck;
}
然后在第一行之前生成这个wrapper, 用这个wrapper取代掉步骤3.)跟步骤6.)的
compliance class:
class Engine::compute(...arguments...)
==> 0. wrapper newChecker(doCheckOrNot);
1. compute1
2. compute2
=> 3. if (!newChecker.check(...)) return the pre-condition is not satisfied
......................
5. foreach cofig in allowed_user_configurations
==> 6. if (newChecker.check(....)) then store this configuration
7. return allowed_configuration
目前这个做法有一些好处:
1. 不动到compliance checker, 而且也不用怕compliance checker的interfance of
check function会改变(用template+perfect forwarding处理掉了)
2. 整个流程不变 逻辑上也很分明 就是有检查跟永远成功这两种
但是有些不顺的地方:
1.这个wrapper class定位很尴尬, 不知道要当作一个放出来给大家用的class 或是该
跟谁绑在一起 绑在一起是指逻辑关系上.......现在wrapper class九成像syntax sugar
我直接放在CPP file的 anonymous的namespace里 XDDDDD
未来 若别的地方遇到同一种状况 是不是又要写一次? 要不然就要把这个有template的
wrapper class放在header, 但这样会引进compliance class的dependency.....
2. 要改写成virtual function的形式吗? 这样可继承之类的
但因为有用到template所以 没法用virtual function, 而且只有两种状况
用virtual是否有效益呢?
3. wrapper class生成后 就决定他的行为了(由ctor的参数决定) 要动态变化就得再多
一组setter/getter. 想要动态变化的理由是 这样wrapper可当作一个member variable..
不知道要当作local variable还是member variable比较好......
其实觉得这种状况应该是一个非常标准且常见的状况(二选一) 只是不晓得一般是怎么
处理的 觉得应该是继承+virtual function处理居多吧? 但个人比较倾向少用继承
先尝试template + 组合的方式, 或是virtual function是做在别的地方的方式
P.S. compliance checker是我们动不了的一个class.......
在此 想请各位给一些想法跟建议~~~谢谢~~~
作者: CoNsTaR ((const *))   2023-10-30 08:41:00
你这个这么 procedure 的东西,如果是 business logic 就照着 business logic 的架构写,例如如果 business logic在这边就是每次都先确认是否做检查,那你就照着它架构写,每个检查外面都包上 if else,不要做一些自以为聪明的"设计"如果 business logic 在这边有做抽象,例如要检查和不检查被分成两种不同的流程,在不同情况下使用,两种流程有各自的名字,那就把两种流程分成两个函式,不要自以为写成一个函式 reusing 很聪明如果这不是 business logic 而是你为了达成 business logic 而写出来的算法,那我只能说真的惨
楼主: saladim (杀拉顶)   2023-10-31 03:17:00
意思是说直接if-else吗? 比起继承我还比较可以接受 继承太难model了 对了 这边是简化过的程式 实际上复杂许多 很多地方要考虑加 基本上是一个template+strategy pattern的组合 设定/caller无关的都拿掉了 不是单单一堆functioncall..另外我的一个疑问就是 通常有个二选一的选项 但是要嘛做个抽象有点多余(因为永远不会有更多选项) 要嘛 无法用现有体系去model这个抽象 或是它本身就是一个独立的不知道一般是怎么处理 这个case, 因为流程固定了所以两个是不行的......以上....大概补充说明一下.....
作者: CoNsTaR ((const *))   2023-10-31 11:07:00
你比较可以接受继承的具体原因我没看到?如果你对 if else 的 concern 只是像你内文说的"怕以后忘记加",那你可能要再想想,我不太能理解忘记做该做的工作是个什么概念1. 你用 if else 不会影响未来制定 business logic 的人考虑到检查/不检查两种情况2. 也不会影响未来写 jira ticket 的时候的 description和 acceptance criteria 忘记这两种情况3. 也不会影响原本该做的 code review 变成没做4. 也不会影响 unit tests 忘记测5. 也不会影响 testers 的 test plan 忘记加这个测项完全看不出来怎么会影响任何一个人忘记考虑检查/不检查两种情况看你的内文和回复感觉最大的问题是你在用写通用函式库的思维写 user code,这样写出来的东西不觉得就像是用营造业 sop 盖的叠叠乐一样吗
作者: wulouise (在线上!=在电脑前)   2023-10-31 12:32:00
不懂你说的忘记加是什么情况,多了cpmpute忘记补检查?general就是所有compute都有check,只是chk可以noop或所有compute跟check都当做callback执行,继承没有必要如果对效能有需求,那看情况决定要不要generalize重点是你的抽象化可以用在别的地方吗?好debug吗?
作者: Dracarys (MayShowGunMore)   2023-11-01 09:06:00
改用rust的operator?
楼主: saladim (杀拉顶)   2023-11-02 03:14:00
继承对我的顺位会在第二或更之后 怕忘了加是有了这logic在 若是要改or加新的处理(不是其他bussiness logic变动)在做check的时候 可能会忘记有这条 实际的东西还蛮多的若不是用同一个util(不管是func or class) 会有机会漏掉当然1~5也有道理 其他大大建议我也会一并想一想 其实不到写通用函式库 当会很多东西常出现 但组合他们的逻辑变动很快(bussiness logic/requests...) 一定会有一个自己的"好用函式库/engine库" XD 才能改得快 重复使用"解"
作者: bizer (bizer)   2023-11-04 10:30:00
最个macro取代不就好了?搞这么复杂?
作者: LPH66 (-6.2598534e+18f)   2023-11-04 12:29:00
我会认为这个“选项”应该要是 business logic 的一部份是的话其实也没什么“忘了”的问题, 因为那就是没实作完全如果未来要加其他开关的话应该要以等同改变 business logic的型式去处理, 而不只是加一个开关调整这种事讲更简单一点就是, 加开关应该要以等同于改流程的程度对待(实际上真的在改流程, 新增某条件之下某流程可跳过的逻辑)未来不管是加别的开关或是流程调整都要顺过整个流程才实作这样这些开关是流程的一部份, 就不会有什么“忘记”的问题
作者: a731977 (卡哇邦卡)   2023-11-06 03:30:00
DP, chain of responsibility 参考看看,对于流程控管非常好用
作者: AiriMania (あいりまにあ)   2023-12-02 13:43:00
楼下板桥知名ID Elio2021

Links booklink

Contact Us: admin [ a t ] ucptt.com