Java 将派生类的所有setter放置到util类是一个好的设计吗?

Java 将派生类的所有setter放置到util类是一个好的设计吗?,java,design-patterns,Java,Design Patterns,我读过一些类似这样的代码: public class Base { protected Map<String, Object> attrMap = new HashMap<>(); public Map<String, Object> getAttrMap() { return this.attrMap; } } public class DerivedA extends Base{} public class De

我读过一些类似这样的代码:

public class Base {
    protected Map<String, Object> attrMap = new HashMap<>();
    public Map<String, Object> getAttrMap() {
        return this.attrMap;
    }
}

public class DerivedA extends Base{}

public class DerivedB extends Base{}

public class Util {
    public void setDerivedAAttrX(Base base, Object object) {
        base.getAttrMap().put("DERIVEDA_X", object);
    }
    public void setDerivedAAttrY(Base base, Object object) {
        base.getAttrMap().put("DERIVEDA_Y", object);
    }
    public void setDerivedBAttrX(Base base, Object object) {
        base.getAttrMap().put("DERIVEDB_X", object);
    }
    public void setDerivedAttrZ(Base base, Object object) {
        base.getAttrMap().put("DERIVED_Z", object);
    }
}
公共类基{
受保护的映射attrMap=newhashmap();
公共映射getAttrMap(){
返回此.attrMap;
}
}
公共类DerivedA扩展了基{}
公共类DerivedB扩展基{}
公共类Util{
公共void setDerivedAAttrX(基本、对象){
base.getAttrMap().put(“DERIVEDA_X”,对象);
}
public void setDerivedAAttrY(基本、对象){
base.getAttrMap();
}
public void setDerivedBAttrX(基本、对象){
base.getAttrMap();
}
公共void setDerivedAttrZ(基本、对象){
base.getAttrMap();
}
}
我问那些代码的实现者为什么要这样设计,他的答案如下:

  • 我们不能让
    Base
    中的那些setter,因为它是设置派生属性的
  • 如果我们将这些setter移动到相应的派生类,则很难处理
    setDerivedAttrZ
    (注意,它可以为
    DerivedA
    DerivedB
    设置属性Z)。我们可能有一个
    Base
    引用,我们将设置属性Z。我们知道它确实是
    DerivedA
    DerivedB
    ,但我不知道到底是哪一个。所以我们不能将其强制转换为派生类并调用派生的setter
  • 由于将这些setter放在
    Base
    或派生类中都有一些缺点,因此他使用
    Util
    类来处理这些setter

  • 所以我的问题是,这是一个好的设计吗?

    我认为这是一个坏的设计。面向对象编程的基础是对对象调用方法,而不是向其传递对象和方法参数的辅助函数。

    。这意味着几个类具有各种各样的功能,有些是共享的。 而且是非类型化的

    一个改进是使用具有功能的接口,并将其作为关键

    public class Base {
        private Map<Class<?>, Object> attrMap = new HashMap<>();
    
        protected <T> void add(Class<T> clazz, T object);
    
        /** @return null when not available. */
        public <T> T lookup(Class<T> clazz) {
            Object object = attrMap.get(clazz);
            return clazz.cast(object);
        }
    }
    
    公共类基{
    
    私有映射空派生类的意义是什么?它们与
    Base
    完全相同,除非您没有向我们展示代码的某些部分。我不会这么说,因为如果
    Util
    类的目的是更新
    Base
    的状态,那么
    Base#getAttrMap
    就不能是公共的,因为任何类都可以访问o使用此方法并根据需要更新状态,甚至可以使用
    Base#getAttrMap#clear
    清除映射。事实上,如果其他类
    DerivedA
    DerivedB
    不会为此设计添加任何值,则不需要它们。在映射中存储属性通常不是一个好主意。如果您知道所有键首先,为什么要使用映射?您的示例看起来很像一个@RogueCSDev在实际情况中,这些派生类中有许多方法和字段。这看起来非常奇怪,并且打破了许多OO原则。也许通过一个不太虚构的示例,我们可以更好地帮助您。从哪里调用这些Util方法?就像现在一样,DerivedB could与DerivedA实例的基本映射相关联……这有什么意义吗?很难从您发布的代码中找出用例,从而找出真正的问题所在。