Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在这种情况下,如何重构或修复循环引用?JAVA_Java_Design Patterns_Refactoring - Fatal编程技术网

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

在这种情况下,如何重构或修复循环引用?JAVA,java,design-patterns,refactoring,Java,Design Patterns,Refactoring,我读过一个叫做MyClass的父类 代码是这样的 public class MyClass extends CompositeObject{ protected Map<String,MyAttibute> attributes = new HashMap<String,MyAttribute> ..... } 这实际上是一个循环引用。当你做深度序列化和相等时,这会带来麻烦。而且这可能不是一个好的设计。如何避免呢?在修复它之

我读过一个叫做MyClass的父类 代码是这样的

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

    HashMap<String,MyAttribute>
    .....

 }
这实际上是一个循环引用。当你做深度序列化和相等时,这会带来麻烦。而且这可能不是一个好的设计。如何避免呢?在修复它之后,我们仍然可以很容易地从它的属性中找到父类

另外,我看到另外两个班级的设计

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;
  ....  
}
公共类事务{
私人变更经理;
....
公共事务(ChangeManager parentManager)
} 
公共类变更管理器{
//提交时记录事务
私有列表事务=新的ArrayList();
交易流交易;
....  
}
你认为这种设计好吗?为什么? 正如您所看到的,这些类定义的域非常常见。
那么,有人能分享一些关于它的见解吗?让事务知道其ChangeManager并让MyAttributes知道其属性中的MyClass是否有害?欢迎提出任何意见。利与弊。

将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的objectstreams的默认序列化可以处理循环引用

如果我理解正确,您的父类有一个对自身子类的引用吗?(这对我来说并不完全清楚,所以如果不是这样的话就忽略这一点)哦,天哪,这绝对不是个好主意——连载的问题只是一个可怕的设计上的糖霜。一个类永远不应该需要或假设它的知识children@Voo,我们在处理序列化时遇到此问题。但是数据模型不是我们设计的。这就是问题所在。好吧,这个问题(特别是“这是一个好的设计吗?”)还不太清楚——应该更多地遵循“我们如何解决这个糟糕的设计”;)但是如果definedOnClass是子类本身,我不知道如何修复它(在这种情况下,没有递归的基本情况);如果不是,我想它应该可以正常工作-确切的错误是什么?解决方法已经存在。那就是使用IdentityHashMap来记录已序列化的对象。当遇到循环引用时,它会为该对象写入映射键。但是我想看到更多的建议或者如何在这两种情况下更好地设计这些类的建议。你的意思是
MyAttibute扩展了MyClass
?我认为你的代码不能工作。这个.definedOnClass.equals(其他.definedOnClass)调用MyClass的equals方法,如果MyClass调用MyAttibute.equals2()而不是equals@ratchel好的,我明白了。你把等分为两部分,这个主意很好。但是代码样式是否可以更干净一些?
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
   }
}