在“清洁代码”一书中,罗伯特·马丁就以下代码发表了一项声明:
public Money calculatePay(Employee e) throws InvalidEmployeeType { switch (e.type) {
case COMMISSIONED:
return calculateCommissionedPay(e);
case HOURLY:
return calculateHourlyPay(e);
case SALARIED:
return calculateSalariedPay(e);
default:
throw new InvalidEmployeeType(e.type); } }语句:这个问题的解决方案(参见清单3-5)是将switch语句埋在抽象工厂的地下室,9而不让任何人看到它。
我不明白的是他为什么叫它抽象工厂?如果解决方案是创建3个Employee子类,每个子类实现自己的CalculatePay方法,那么逻辑将向上移动,例如控制器。但是,我们必须创建一个“简单工厂(成语)”,而不是一个抽象工厂,如GOF的原著所示。
抽象工厂的意图是:“提供一个接口,用于创建相关或依赖对象的系列,而不指定它们的具体类。”但情况显然并非如此。
发布于 2013-10-06 17:06:21
在这个具体的例子中,他可以使用一个简单的Factory来理解开关语句的要点。
但他的另一点是,您应该寻找将依赖最小化的方法。如果您有使用工厂创建employee对象的客户端代码,并且该代码引用了一个具体的(即简单的)工厂类,那么这将比引用EmployeeFactory接口紧密得多。这样,如果由于任何原因,稍后您决定EmployeeFactoryImpl的当前实现对您来说还不够好,那么您就可以简单地定义一个实现相同EmployeeFactory接口的新工厂类实现。
因为您已经在使用抽象工厂,所以所有存储和传递EmployeeFactory接口的代码都不需要被触摸,这将回到OCP原则,尽可能多地编写代码,这样它就不会受到不断的修改,因为每次修改某个东西,都会有破坏它的风险。
因此,Bob叔叔在该示例中没有说明的唯一一点是,您可以用一个完全不同的EmployeeFactoryImpl2 ()方法的实现创建"class makeEmployee implementation EmployeeFactory“,这将完成GoF的示例,但它将向示例添加更多的移动部分,目的是演示完全不同的东西。
另一种是从“清洁规则”( IMO是一本很棒的书,所以继续读它)中拿出来的,那就是模式是在你的脑海中保留的东西,而不是仅仅因为你读了GoF就向左右介绍的东西。因此,更重要的是,Bob叔叔演示的是,这是一个完美的例子,您可以对代码进行小规模的增量重构,以使代码更容易阅读和维护,并且在执行过程中,将模式保留在脑海中,因为没有重新发明已经完成的工作的感觉。
在这种情况下,他直接去了抽象工厂,因为不同的是输入"public class EmployeeFactory“(简单)与"public class EmployeeFactoryImpl implements EmployeeFactory”(抽象)。抽象工厂为您提供了更好的未来位置,阳池在这里不是一个很好的论据,因为这种更好的定位只需要几次击键,而不需要任何额外的复杂性。
https://softwareengineering.stackexchange.com/questions/213571
复制相似问题