“规则很复杂”的价格的建模(续)
Alan 2020-6-2 10:01
在并多的案例中,计算价钱由拼单子订单完成,拼单子订单有数量,就能计算价格,实际上计算价格影响的因子比较多,比如价格,2件以上再打9.5折,顾客类型(高级会员),在总价高于200时还能再0.95折,还有不同的包邮类型决定最后价格,针对并多多的计算价格,采用面向对象来设计,合适的做法有
A. 提供一个计算价格的类 feeCount ,把所有参数传给这个类去算,后续有变更规则,只需要修改此类的逻辑即可
B. 仍在拼单子订单计算,把顾客对象,商品对象的类传入子订单
C. 顾客类型,订单,包邮类型 都有计算价格的接口,根据自己的规则对传入价格再计算一次
D. 放在控制类,从各个对象取出属性,再按规则计算
子订单计算价钱是专家原则么?
如同这里,计算租金的规则也很复杂,只是设备规格搞不定,是否也给设备规格算?
很多采集面向对象,最像就在一个service 把其它对像的属性get出来,然后算一把,能封装修改点,确定也算逻辑内聚,但是在责任分配上确实又不是面向对象
UMLChina潘加宇
凡是“规则很复杂”,需要一个“service”来封装一个“算法”的,很有可能是类图还画得不够细,还得继续剖析背后的知识,而不是藏在“算法”里面
“实际上计算价格影响的因子比较多,比如价格,2件以上再打9.5折,顾客类型(高级会员),在总价高于200时还能再0.95折,还有不同的包邮类型决定最后价格”---这些都要通过类图表达出来
另外,计算价钱之类实际上仍然属于查询,并没有修改对象的状态,所以责任怎么分配,其实问题不大。面向对象的用处主要是,修改数据时能通过状态机维护逻辑的完整性
Alan
嗯,但这个的变动点比较多,较好的封装规则易于维护,也不容易出错。计算出错对业务的影响比较大
UMLChina潘加宇
所以就要通过类图把各个概念之间的关系精细表达出来,而不是搞一个“**计算器”,然后就以为万事大吉了
Alan
系统增加了规则(现实中规则可能更复杂),这几个新增的价格描述规则是否准确,计算价格时实际涉及多个类,放哪个类都需要了解其它类封装规则 ?
还有这一步,用户提交拼单信息,系统验证拼音信息,需要包含商品价格是否对,是不是与前面一步反馈的信息相同,这种考虑是否属于分析工作流内容
UMLChina潘加宇
“决定邮费”那里不够,另外邮费的标准应该不会精细到某个商品,而是商品类别。
关系:商品-商品类别-邮费标准-区域。
商品折扣那里应该是价格区间(单价、数量下限,数量上限)
是否属于分析工作流内容 --把系统的对象看作是在大脑里运行,对象的创建、修改速度无限快,然后你担心的“问题”“逻辑”还存在吗?
如果还存在--那就是分析问题
如果消失了--那就是设计问题
这个区分很重要,因为分析和设计的映射是有规律的,区分好了,人脑要应对的复杂度是m+n,区分不好,就是m×n
例如:商品价格是否对--如果担心的是因为系统的分布问题,造成界面的信息、内存里对象的信息、持久存储里数据的信息有时会不一致,所以要验证一下,那么这个问题在上面的测试中,属于会消失的问题,那是设计问题。而这个设计问题,不只是对商品存在,对顾客、发票、订单等等都存在一模一样的问题,如果不区分,就会在各个地方一遍一遍的重复这样的“逻辑”和“技巧”。
但是,人性有弱点,很多无能之辈会喜欢这样的模式,把同样的东西重复很多遍来充工作量。
Alan 2020-6-9 10:15
价格按这种修改是否更合适
UMLChina潘加宇
可以按这个
价格因子和价格因子特征之间的关系不能砍,自己推敲一下就知道,砍了就没法知道某个特征值是哪个价格因子的了。如果要砍,可以砍价格因子-价格因子类型。
张三这个人身高1.75米,体重60公斤,李四这个人身高1.76米,体重61公斤,王五这只蟑螂触须长3厘米;张三和1.75之间是不能砍的,要砍可以砍“张三属于人类”。
Alan
顾客->顾客类型->折扣率->0.75 按成员关联关系好像能推导出来0.75 是张三的拆扣率
UMLChina潘加宇
你再捉摸捉摸我上面的回答
Alan
好的,关于上面那个计算价格的图,可以按你的模板,责任是否还是子订单,你发的那个图是一个模式,这些类需要关联到订单,顾客类吗?
UMLChina潘加宇
不需要了,包括顾客等级,购买数量这些都可以不要了,变成一个模板项
Alan 2020-6-10 18:35
从EA 生成的代码,从代码的使用逻辑上,通过找到价格因子类型->价格因子类型特征->价格因子特征 ,分析与设计上的偏差,麻烦指教下
UMLChina潘加宇
晕,代码里面都写着是List了,你还能这样一路点下去?
不管这个类叫价格还是叫阿猫阿狗ABCD,看形状就知道了,把连续的*...1合并,就可以看出总的结果是*...1还是*...*。如果是*...*,就无法从一端的某个对象定位到另一端某个对象。