在这种情况下如何重构或修复循环引用?爪哇

发布于 2024-11-17 18:03:35 字数 1009 浏览 1 评论 0原文

我读过一个名为 MyClass 的父类 像这样的代码,

 public class MyClass extends CompositeObject{
    protected Map<String,MyAttibute> attributes = new       

    HashMap<String,MyAttribute>
    .....

 }

在 MyAttribute 类中, 像这样的代码

public class MyAttibute extends MyObject 
{
   private MyClass definedOnClass;//point to its parentClass

}

这实际上是一个循环引用。当您进行深度序列化和等于时,这会带来麻烦。而且这可能不是一个好的设计。如何避免呢?并且修复后,我们仍然可以轻松地从其属性中找到parentClass。

PS我看到另外两个类的设计

public class Transaction{
   private ChangeManager parentManager;
   ....
   public Transaction(ChangeManager parentManager)
} 

public class ChangeManager {
  //record transaction when commit
  private List<Transaction> transactions = new ArrayList<Transaction>();
  Transaction currentTransaction;
  ....  
}

你觉得这样的设计好吗?为什么? 正如您所看到的,这些类定义的域非常常见。 那么有人可以分享一些关于它的见解吗?让 Transaction 知道其 ChangeManager 并让 MyAttributes 知道其属性中的 MyClass 是否有害?欢迎任何评论。缺点和优点。

I have read a parent Class called MyClass
code like this,

 public class MyClass extends CompositeObject{
    protected Map<String,MyAttibute> attributes = new       

    HashMap<String,MyAttribute>
    .....

 }

In MyAttribute Class,
Code like this

public class MyAttibute extends MyObject 
{
   private MyClass definedOnClass;//point to its parentClass

}

This actually is a circular reference.Which makes trouble when you do deep serlization and equals. And it may not be a good design.How to avoid it? And after fixing it, we can still easily find the parentClass from its attribute.

P.S. I see another two classes design

public class Transaction{
   private ChangeManager parentManager;
   ....
   public Transaction(ChangeManager parentManager)
} 

public class ChangeManager {
  //record transaction when commit
  private List<Transaction> transactions = new ArrayList<Transaction>();
  Transaction currentTransaction;
  ....  
}

Do you think this kind of design is good? Why?
As you can see the domains these classes are defining on are quite common.
So can anyone share some insight about it? Is it harmful to let Transaction know its ChangeManager and let MyAttributes know its MyClass in their properties? Any comments are welcome. Cons and pros.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

花落人断肠 2024-11-24 18:03:35

将 MyAttibute 作为逻辑上独立于父级的子级,因此 attr1.equals(attr2) 不涉及各自的父级(与序列化相同;不将其包含在流中),并且您可以保留 DefinedOnClass 属性

,也可以使用从 MyClass 进行测试时使用不同的 equals 方法

public class MyAttibute extends MyObject 
{
   private NgcClass definedOnClass;//point to its parentClass

   public boolean equals(Object o){
       if(o instanceof MyAttibute){
           MyAttibute other = (MyAttibute)o;

           if(!this.definedOnClass.equals(other.definedOnClass))
                return false;//when not from the same parent they are never the same

           return this.equals2(other);
       }
       return false;
   }

   //this one should then be called from MyClass
   public boolean equals2(MyAttibute o){
       //check equality without worrying about definedOnClass
   }
}

,请注意 java 对象流的默认序列化可以处理循环引用

put the MyAttibute as a child logically independent of the parent so attr1.equals(attr2) doesn't involve the respective parents (same with serialization; don't include it in the stream) and you can keep the definedOnClass property

or you can use a different equals method when testing from MyClass

public class MyAttibute extends MyObject 
{
   private NgcClass definedOnClass;//point to its parentClass

   public boolean equals(Object o){
       if(o instanceof MyAttibute){
           MyAttibute other = (MyAttibute)o;

           if(!this.definedOnClass.equals(other.definedOnClass))
                return false;//when not from the same parent they are never the same

           return this.equals2(other);
       }
       return false;
   }

   //this one should then be called from MyClass
   public boolean equals2(MyAttibute o){
       //check equality without worrying about definedOnClass
   }
}

note that the default serialization of java's objectstreams can handle circular references

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文