减少类的复杂性
我已经查看了一些答案并在Google上进行了搜索,但是找不到任何有用的东西(即不会产生尴尬的副作用)。 总的来说,我的问题是我有一个对象,需要对它执行长时间的操作。我将其视为一种装配线,例如制造汽车。 我相信这些对象将称为“ 方法对象”。 因此,在此示例中的某个点上,我将拥有一个CarWithoutUpholstery,然后需要在其上运行installBackSeat,installFrontSeat,installWoodenInserts(这些操作不会互相干扰,甚至可以并行执行)。这些操作由CarWithoutUpholstery.worker()执行,并产生一个新的对象,该对象将是CarWithUpholstery,然后在其上运行cleanInsides(),verifyNoUpholsteryDefects()等。 单个阶段中的操作已经是独立的,也就是说,我已经在努力应对可以按任何顺序执行的子集(可以按任何顺序安装前排和后排座椅)。 我的逻辑当前使用反射来简化实现。 也就是说,一旦有了CarWithoutUpholstery,该对象就会检查自身是否有名为performSomething()的方法。此时,它执行所有这些方法: myObject.perform001SomeOperation(); myObject.perform002SomeOtherOperation(); ... 同时检查错误和内容。虽然操作的顺序是不重要的,我已经在指定情况下,我曾经发现毕竟一些顺序很重要,一个字典顺序。这与YAGNI矛盾,但是它花费很少-简单的sort()-并且可以节省大量的方法重命名(或引入其他执行测试的方法,例如方法数组)的费用。 一个不同的例子 让我们说,除了要制造汽车外,我还必须编辑某人的秘密警察报告,并将其提交给我的邪恶霸主。我的最后一个对象将是ReadyReport。为了构建它,我首先收集基本信息(姓名,姓氏,配偶...)。这是我的A阶段。根据是否有配偶,我可能不得不进入B1或B2阶段,并收集一两个人的性行为数据。这是由对不同的Evil Minions的几个不同的查询所组成,它们控制着夜生活,街拍,性用品商店的销售收据以及不收什么。等等等等。 如果受害者没有家庭,我什至不会进入GetInformationAboutFamily阶段,但是如果我这样做了,那么我是首先瞄准父亲还是母亲还是兄弟姐妹(如果有)就没有关系了。但是,如果我还没有执行FamilyStatusCheck,那我就无法做到这一点,因此它属于早期阶段。 一切都很棒... 如果我需要一些其他操作,我只需要添加一个私有方法, 如果该操作在多个阶段都是通用的,那么我可以让它从超类继承, 操作简单且自成体系。任何其他操作都不需要从任何操作中获得任何价值(在不同阶段执行的操作), 线下的对象不需要执行许多测试,因为如果其创建者对象首先没有验证这些条件,它们甚至可能不存在。即,在将插入物放入仪表板,清洁仪表板并验证仪表板时,我不需要验证仪表板是否确实存在。 它便于测试。我可以轻松模拟部分对象并在其上运行任何方法,并且所有操作都是确定性的黑匣子。 ...但... 当我在我的方法对象之一中添加最后一个操作时,就会出现问题,这导致整个模块超过了强制性的复杂性指标(“少于N个私有方法”)。 我已经在楼上解决了这个问题,并建议在这种情况下,私有方法的丰富并不是灾难的故事。复杂性是存在的,但它的存在,因为操作是复杂的,实际上它不是那么复杂-它只是长。 以邪恶的霸王为例,我的问题是邪恶的霸王(又名不容否认的他)要求了所有饮食信息,我的饮食奴才告诉我,我需要查询餐馆,小厨房,街头小贩,无牌街头小贩,温室所有者等,以及邪恶的(sub)Overlord(众所周知的也不应被拒绝的他)抱怨我在GetDietaryInformation阶段执行了太多查询。 注意:我知道从多个角度来看这根本不是问题(忽略可能的性能问题等)。发生的一切是,一个特定的指标不满意,对此有充分的理由。 什么我想我能做到 除了第一个以外,所有这些选择都是可行的,而且我认为是可以辩护的。 我已经证实自己可以偷偷摸摸,并声明一半的方法protected。但是我会利用测试程序中的弱点,除了在被抓住时证明自己是合理的之外,我也不喜欢这样。另外,这是权宜之计。如果所需操作次数加倍怎么办?不太可能,但是那又如何呢? 我可以将此阶段任意拆分为AnnealedObjectAlpha,AnnealedObjectBravo和AnnealedObjectCharlie,并使每个阶段要执行的操作占三分之一。我的印象是,这实际上增加了复杂性(增加了 N-1个类),除了通过测试之外没有任何好处。我当然可以认为,CarWithFrontSeatsInstalled和CarWithAllSeatsInstall在逻辑上是连续的阶段。Alpha后来要求使用Bravo方法的风险很小,如果我打得很好的话,风险甚至会更低。但是还是。 我可以将一个远程相似的不同操作组合在一起。performAllSeatsInstallation()。这只是权宜之计,并且确实增加了单个操作的复杂性。如果我需要以不同的顺序执行操作A和B,并且将它们打包在E =(A + C)和F(B + D)内,则必须解开E和F并重新整理代码。 我可以使用lambda函数数组,并完全避开检查,但是我发现这很笨拙。但是,这是迄今为止最好的选择。它会摆脱反思。我遇到的两个问题是,可能会要求我重写所有方法对象,不仅是假设对象,CarWithEngineInstalled而且这虽然是很好的工作安全性,但实际上并没有那么大的吸引力。并且代码覆盖率检查器存在lambda 问题(可以解决,但仍然存在)。 所以... 您认为哪个是我最好的选择? 有没有我没有考虑过的更好的方法?(也许我最好打扫卫生,直接问一下是什么?) 这种设计是否存在绝望的缺陷,我最好承认失败与否-这种体系结构?这对我的职业生涯不利,但是从长远来看,编写错误的代码会更好吗? 我当前的选择是否真的是“唯一的方式”,我需要努力获得更好的质量指标(和/或仪器)?对于这最后一个选项,我需要参考...我不能只在抱怨的同时对@PHB挥手,这不是您要查找的指标。不管我想要多少