gpt4 book ai didi

java - 在java中扩展参数化工厂方法

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:18:20 26 4
gpt4 key购买 nike

我是 OOP 的新手,正在学习设计模式,所以我编写了一些简单的代码来尝试工厂方法,一切似乎都很好,除非我想添加另一个子类型。到目前为止,这是代码:

public interface Person {
public String getDescription();
}

public class Adult implements Person {
@Override
public String getDescription() {
return "I am an ADULT";
}
}

public class Child implements Person {
@Override
public String getDescription() {
return "I am a CHILD";
}
}

public class PersonFactory {
public Person create(int age) {
if (age < 18) return new Child();
return new Adult();
}
}

public class ClientA {
public static void main(String[] args) {
PersonFactory personFactory = new PersonFactory();
Person person;
person = personFactory.create(80);
System.out.println(person.getDescription());
}
}

如果以后要求更改为包括年龄 > 70 时的子类 Pensioner,我将不得不:

将行 if (age > 70) return new Pensioner(); 添加到 PersonFactory 类的 create() 方法中,这肯定会打破开闭原则?或者,如 The Gang Of Four Design Patterns 一书中所建议的那样,覆盖参数化工厂方法以有选择地扩展 Creator 生产的产品。在这种情况下,我认为这意味着编写一个新类:

public class PersonFactoryWithPensioner extends PersonFactory { 
@Override
public Person create(int age) {
if (age > 70) return new Pensioner();
return super.create(age);
}
}

这意味着现在必须将调用 PersonFactory 的所有客户端更改为使用 PersonFactoryWithPensioner,或者我必须接受新客户端可以调用PersonFactoryWithPensioner 而老客户,例如。 ClientA 仍然只会在年龄 > 70 时收到一个 Adult 对象。如果稍后在另一个子类上,情况会变得更糟,例如。添加了 Infant。为确保新客户端接收合适的 InfantChildAdultPensioner 对象,一个新类PersonFactoryWithInfant 必须扩展 PersonFactoryWithPensioner。这不可能是对的,似乎我误解了 GoF 的建议。

我的问题是:有没有一种方法可以添加一个新的子类型,它可以在不更改旧客户端的情况下返回给旧客户端,并且不会通过更改 PersonFactory 代码以包含新的来破坏 OCP子类型?

如果我没有正确发布这个问题,我深表歉意,这是我第一次在这里发布问题。我已经查看了以前针对类似问题的答案,但它们似乎并没有完全解决这个问题。

最佳答案

我认为 OCP 不会停止修改任何方法或类。

但是,它建议如果您需要进行任何修改,您应该这样做,这样您就不必再次修改该代码。

鉴于您稍后可能需要修改 PersonFactory - 您可以创建另一个 Factory 类来创建类型为 PersonFactory 的对象。尽管这似乎是过度设计的解决方案。

另一种可能的解决方案是 PersonFactory 从一些动态源加载此规则,例如,使用 JSON 格式将此规则保存在文件中。然后使用反射动态创建对象。

像这样:

 private static JSONObject RULES;
static {
RULES= JSON.parse(rulesEngine.load());
}
public class PersonFactory {
public Person create(int age) {
String personToCreate = RULES.get(age);
Constructor<?> ctor = Class.forName(personToCreate).getConstructor();
return (Person) ctor.newInstance();
}
}

json 规则是这样的:

{
"1":"Child.class",
"2":"Child.class",
...,
"17":"Child.class",
"18":"Adult.class",
...,
"69":"Adult.class",
"70":"Pensioner.class"
}

这样您就不会违反 OCP 原则。

关于java - 在java中扩展参数化工厂方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41768175/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com