【问题标题】:Java object graph visitor libraryJava 对象图访问者库
【发布时间】:2010-07-29 10:39:08
【问题描述】:

你知道一个好的java对象图访问器库吗?

我想访问一个对象及其子组件,并在某些条件匹配时执行一些操作。

用法示例:

  • 在一个巨大的域对象图上,重置 每个id到null
  • 在一个巨大的域对象图上,将每个Set 替换为TreeSet 包含相同的实例 元素。

我想要一个库,而不是自定义代码,因为遍历对象图可能很棘手。你必须处理集合、数组、代理等等...... 我曾考虑重用 XStream 的一部分来实现这一点,但看起来并不那么容易:Xstream 访问者更面向对象转换而不是对象自我修改。

【问题讨论】:

    标签: java introspection visitor-pattern object-graph


    【解决方案1】:

    我一直在寻找同样的东西,并找到了这个。

    http://code.google.com/p/behaim/

    【讨论】:

      【解决方案2】:

      碰巧,我做过这样的事情。不是一个真正的图书馆,但它可以很容易地成长为一个图书馆。

      但我偶然发现了这一点,因为我正在寻找更好的东西。我不能给出它,而且它肯定还没有处于我会这样做的状态,但也许这样的东西应该作为操作系统来生活?

      我所拥有的让我可以遍历和修改对象图类型安全、逐个实例,可以选择复制它以使原始对象保持不变。 Java 顺便说一句。也有点作用的是掌握图中的关系(如果你愿意的话,边缘)。

      我可以设想的是对操作(例如修改、扩展、复制、折叠、遍历)和相应实现的明确定义。诸如识别子图之类的正交方面将被适当地分解。

      任何对此类项目感兴趣的人请回复,也许我们可以开始做一些事情。

      【讨论】:

        【解决方案3】:

        为什么需要图书馆才能做到这一点?

        鉴于您指定这是一个域对象图,那么为什么不定义和实现相关接口以允许不同的访问者实现访问您的域对象呢?其中一种实现可以(如您指定)将每个 ID 重置为 null

        示例

        首先定义可以访问或作为访问者的对象要实现的接口。

        public interface Visitable {
          void visit(Visitor visitor);
        }
        
        public interface Visitor {
          void visitDomainObjectA(DomainObjectA obj);
          void visitDomainObjectB(DomainObjectB obj);
        }
        

        现在定义两个域对象类,它们都可以访问。

        public abstract class DomainObject implements Visitable {
          private Object id;
        
          public Object getId() { return this.id; }
          public void setId(Object id) { this.id = id; }
        }
        
        public class DomainObjectA extends DomainObject {
          public void visit(Visitor visitor) {
            visitor.visitDomainObjectA(this);
          }
        }
        
        public class DomainObjectB extends DomainObject {
          public void visit(Visitor visitor) {
            visitor.visitDomainObjectB(this);
          }
        }
        

        现在定义一个做一些有用的具体访问者实现:

        public class MyVisitor implements Visitor {
          public void visitDomainObjectA(DomainObjectA doa) {
            doa.setId(null);
          }
        
          public void visitDomainObjectB(DomainObjectB dob) {
            doa.setId(UUID.randomUUID());
          }
        }
        

        【讨论】:

        • 我已经完善了关于您的相关答案的问题。我的领域很大,我的图表很复杂。所以我需要一些健壮的、已经调试好的并且可以使用的东西。
        • IMO 你试图成为超级通用的,使问题变得棘手。可以遍历 any 对象图(可能是通过反射)然后在给定对象上调用 any 方法 的库有什么意义?您有效地抛弃了任何编译时类型安全。毕竟,可以说任何 OO 应用程序都只是简单地遍历对象图并调用对象子集上的方法。
        • 我不想成为超级通用的。我的领域非常复杂;)顺便说一句,这就是像 XStream 这样的序列化工具的工作方式。他们工作正常。
        【解决方案4】:

        如何将您的对象图编组为 XML 并使用一些标准的 XML 处理/操作库?

        【讨论】:

        • 这是一个很好的建议,但我想尽可能避免它。它添加了一些我希望可以避免的步骤
        【解决方案5】:

        可能值得尝试像Neo4jTitanDB 这样的图形数据库。它可以让您通过使用查询来横切您的数据集并探索关系来影响访问。

        这两者都有广泛的 Java API 以方便数据加载和查询。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多