设计模式来处理子类中的设置?

时间:2010-09-27 15:02:41

标签: java design-patterns

我有一个小的层次结构,它们都实现了一个公共接口。

每个具体类都需要接收一个包含例如公共字段的设置结构。问题是设置结构

  • 有一个所有类共有的部分
  • 有另一部分,从一个具体类到另一个不同

我想知道你是否有任何优雅的设计来处理这个问题。我想构建类似的东西:

BaseFunc doer = new ConcreteImplementation1();

使用ConcreteImplementation1实现BaseFunc。并且有像

这样的东西
doer.setSettings(settings)

但是''settings''对象具有适合ConcreteImplementation1的具体实现。

你会怎么做?

6 个答案:

答案 0 :(得分:2)

这可能是一个命名的设计模式,如果是,我不知道名字。 声明一个实现所需接口的抽象类。抽象类构造函数应该采用您的设置对象的实例,从中提取全局设置。从抽象类派生一个或多个类。派生类构造函数应该获取设置对象的实例,将其传递给父类构造函数,然后提取任何本地设置。

以下是一个例子:

class AbstractThing implements DesiredInterface
{
    private String globalSettingValue1;
    private String globalSettingValue2;

    protected AbstractThing(Settings settings)
    {
        globalSettingValue1 = settings.getGlobalSettingsValue1();
        globalSettingValue2 = settings.getGlobalSettingsValue2();
    }

    protected String getGlobalSettingValue1()
    {
        return globalSettingValue1;
    }

    protected String getGlobalSettingValue2()
    {
        return globalSettingValue2;
    }
}

class DerivedThing extends AbstractThing
{
    private String derivedThingSettingValue1;
    private String derivedThingSettingValue2;

    public DerivedThing(Settings settings)
    {
        super(settings);
        derivedThingSettingValue1 = settings.getDerivedThingSettingsValue1();
        derivedThingSettingValue2 = settings.getDerivedThingSettingsValue2();
    }
}

答案 1 :(得分:1)

听起来你需要一个非常标准的Visitor pattern

简单地说,假设您的所有属性都存储为地图中的键值对。并且您的层次结构中有3个类:A,B,C。它们都实现了一些通用接口CI。

然后你需要创建一个这样的属性持有者:

public class PropertyHolder {

    public Map<String, String> getCommonProperties () { ... }

    public Map<String, String> getSpecialPropertiesFor (CI a) { return EMPTY_MAP; }

    public Map<String, String> getSpecialPropertiesFor (A a) { ... }

    public Map<String, String> getSpecialPropertiesFor (B b) { ... }

    ...
}

所有类都应该实现在接口CI中声明的1个方法getSpecialProperties。实现简单如下:

public Map<String, String> getSpecialProperties (PropertyHolder holder) {
   return holder.getSpecialPropertiesFor (this);
}

答案 2 :(得分:1)

具有匹配的设置对象层次结构,使用Factory创建与特定类匹配的设置。

答案 3 :(得分:0)

我沿着这条路走了一次。它起作用了,但在决定之后它不值得。

您可以定义基类MyBean或其他东西,它有自己的mergeSettings方法。您希望使用此框架的每个类都可以扩展MyBean,并为调用超类mergeSettings的mergeSettings提供自己的实现。这样,公共字段可以在超类上。如果你想得到真正的幻想,你可以定义和接口和抽象类,以真正使它漂亮。虽然你在它,也许你可以使用反射。无论如何,mergeSettings将采用一个Map,其中键是属性名称。每个类都有与常量相关的常量。

 class MyBean extends AbstractMyBean ... {
       public static final String FIELD1 = 'field1'

       private String field1

       public mergeSettings(Map<String, Object> incoming) {
            this.field1 = incoming.get(FIELD1);
            // and so on, also do validation here....maybe put it on the abstract class
       }


 } 

虽然它为安装者做了很多工作......

答案 4 :(得分:0)

我开始玩一种新模式,我称之为“类型安全对象映射”。它就像一个Java Map,但值有类型。这允许您定义每个类想要读取的键,并以类型安全的方式获取值(没有运行时成本!)

See my blog for details

关于这一点的好处是它仍然是一张地图,因此您可以轻松实现继承,通知等。

答案 5 :(得分:0)

您可以使用Generics定义此实例所需的设置类型。像这样:

public abstract class MySuperClass<T extends MySettingsGenericType>{
    public MySuperClass(T settings){
         //get your generic params here
    }

}

public class MyEspecificClass extends MySuperClass<T extends MySettingsForThisType>{
    public MySuperClass(T settings){
         super(settings);
         //Get your espefic params here.
    }

}

//and you could use this
BaseFunc doer = new ConcreteImplementation1(ConcreteSettingsFor1);

//我不编译这段代码并急着写。对不起,如果有一些错误...