寻找有关使用适配器模式的反馈

时间:2009-06-28 02:35:16

标签: java design-patterns inheritance domain-driven-design adapter

在工作项目中,我们的域模型中有一个特定的值类型类,其中包含大量属性...

public class BigValueType {
    private Foo foo;
    private Bar bar;
    private Baz baz;

    //...
}

我们已经意识到我们希望将它“集中”到许多不同的,稍微更专业的类中,这些类只有该类属性的某个子集。我想我们希望对这些数据有不同的“看法”。

public class SpecializationA {
    private Foo foo;
    private Baz baz;
    //...
}

public class SpecializationB {
    private Bar bar;
    private Baz baz;
    //...
}

private class SpecializationC {
    private Foo foo;
    private Bar bar;
    //...
}

但是,此域模型应该是相当通用的,而不是特定于此项目。它将在未来的项目中添加特定于项目的扩展,但是通用域模型将与这些扩展分开。如果我们现在简单地定义一堆类,那么使用域模型的其他项目可能只需要稍后编写自己稍微不同的类。 (我们无法轻易预测这些数据的哪些视图会有用。)

我认为我们应该做的是为这个提供数据的不同视图的大类编写特定于项目的Adapters。这样,域的未来用户不必触摸“公共”域模型中的任何内容来定义此信息的新视图。

public class AdapterA {
    private BigValueType wrapped;
    //...

    public ViewA(BigValueType wrapped) {
        //...
    }

    public Foo getFoo() {
        return wrapped.getFoo();
    }

    //...
}

这对我来说比正常继承更有意义,因为我们的顶级类/接口几乎没有任何内容。

有关此方法的任何反馈意见?

3 个答案:

答案 0 :(得分:1)

首先,了解您想要解决的问题非常重要。拥有一个具有大量属性的类并不一定是坏的,如果你想重构只是为了符合'好'的设计原则,我会重新考虑这个决定。

话虽如此,这是SOA世界中相当常见的设计。您有一个大型服务,它将具有相当多属性的复杂消息作为请求。然后,该服务被“调整”以满足具有不同需求的客户。所以,你的设计应该运作良好。当然,它预先假定您已经知道所有可能的“视图”,或者您必须为新客户编写新的适配器。

这种“适应”可以在两个层面上执行 - 用户界面层面(基本上是你的设计 - 适应班级)或者在较低层面,例如在数据库层面,这反过来修改你的主要课程也是。这取决于您的应用程序,框架的用户等等。

另一种考虑的方法也可以是REST方式 - 暴露数据(Foo,Baz等),尽管来自主类,并让客户端使用主类自己处理数据本质上为这些数据提供CRUD功能。然后你的类更像是一个没有真正业务逻辑的结构。

这三种方法中的任何一种都应该没问题,恕我直言。

答案 1 :(得分:0)

好吧..好像对我好。我认为使用组合的解决方案远比使用继承更好,它会影响你的模型大时间并产生大量低内聚类。

答案 2 :(得分:0)

我发现跨多个项目共享代码的目标比听起来更难。至少,很难让它正确!这正是您讨论的原因,而不是确切知道您在某个新项目中可能需要哪些功能。问题是适配器问题不能解决这个问题(如果底层对象不支持所需的功能集,那就是)。

我建议您使用interfaces 作为单独的项目,但是您需要单独编写实现。如果您发现自己将完全编写相同的代码3次,则将其拉出到公共库中。尽量让您的图书馆保持轻量级。

以后管理多个依赖项可能会很昂贵,当您发现需要添加功能时 - 可能是冲突的 - 并且您可能会影响许多应用程序。