Java 在对象之间共享私有实例可以吗?

Java 在对象之间共享私有实例可以吗?,java,private-members,Java,Private Members,我只允许在我正在学习的编程课程中使用私人成员,我想知道这样做是否合适 public class View { private Model object_; public View(Model object) { object_ = object; //blah blah blah } //blah blah blah } public class Controller { private Model object_; publ

我只允许在我正在学习的编程课程中使用私人成员,我想知道这样做是否合适

public class View {
    private Model object_;
    public View(Model object) {
       object_ = object;
       //blah blah blah
    }
//blah blah blah
}

public class Controller {
    private Model object_;
    public Controller(Model object) {
       object_ = object;
       //blah blah blah
    }
//blah blah blah
}

public class MainClass {
    public static void main(String [ ] args) {
        Model m = new Model();
        Controller c = new Controller(m);
        View v = new View(m);
        //blah blah blah
    }
}

视图和控制器类都持有与私有字段相同的模型实例。这可以接受吗?这似乎违反了私有领域的概念。我试着问我的教授,他说没问题,但我不确定他是否理解我的问题,或者我是否理解他的答案:)

据我所知,没有硬性的“私人领域定律”规定一个物体可以被多个阶级私下持有。对于不可变引用类之类的对象,多个类实例可以接收不可变引用类并将其作为私有属性保存是有意义的

在您的示例中,Carl是对的——视图和控制器通常应该在某些方法中将模型作为参数,而不是保留对它们的引用。所以代码看起来更像这样:

public Response handleRequest(Request request) {
    Controller c = new Controller();
    Model m = c.processRequest(request);
    View v = new View();
    Response response = v.createResponse(model);
    return response;
}

据我所知,没有硬性的“私人领域法则”规定一个物体可以被多个阶级私下持有。对于不可变引用类之类的对象,多个类实例可以接收不可变引用类并将其作为私有属性保存是有意义的

在您的示例中,Carl是对的——视图和控制器通常应该在某些方法中将模型作为参数,而不是保留对它们的引用。所以代码看起来更像这样:

public Response handleRequest(Request request) {
    Controller c = new Controller();
    Model m = c.processRequest(request);
    View v = new View();
    Response response = v.createResponse(model);
    return response;
}
如果查看,您将看到理想情况下控制器位于模型和视图之间。因此,我可能会重新组织您的依赖关系(在这方面存在一些分歧-见下文)

但是你的问题的答案(不管是哪个领域)是你可以共享这些私人参考。理想情况下,它们应该是对接口的引用,并且实现可以在不更改依赖类的情况下进行更改。因此(例如)您将有一个
模型
接口和一个实现
模型impl
,共享引用的类型将是
模型
。然后,您可以在以后替换不同的实现,而不会影响大部分代码。

如果查看,您会发现理想情况下控制器位于模型和视图之间。因此,我可能会重新组织您的依赖关系(在这方面存在一些分歧-见下文)


但是你的问题的答案(不管是哪个领域)是你可以共享这些私人参考。理想情况下,它们应该是对接口的引用,并且实现可以在不更改依赖类的情况下进行更改。因此(例如)您将有一个
模型
接口和一个实现
模型impl
,共享引用的类型将是
模型
。然后,您可以在以后替换不同的实现,而不会影响大部分代码。

是的,这是可以接受的,应该使用私有字段来强制封装,如果需要,可以通过getter/setter方法控制对这些字段的访问。如果这些字段是公共的,甚至是打包的,那么外部类可能开始依赖于类的实现,这在重构方法等方面限制了您。允许其他类访问它们应该访问的字段可能会导致隐私泄漏

如果模型是公共的

课堂混乱 {

模型aModel=对象u2;; aModel.dowhat hell liwant to your model()

}


这可以完全消除系统的状态。

是的,这是可以接受的,应该使用私有字段来强制封装,如果需要,可以通过getter/setter方法控制对这些字段的访问。如果这些字段是公共的,甚至是打包的,那么外部类可能开始依赖于类的实现,这在重构方法等方面限制了您。允许其他类访问它们应该访问的字段可能会导致隐私泄漏

如果模型是公共的

课堂混乱 {

模型aModel=对象u2;; aModel.dowhat hell liwant to your model()

}


这可以完全评估系统的状态。

关于标题问题:是的,没问题。设想一棵树,其中兄弟姐妹共享对父级的引用。这种情况很常见。

关于标题问题:是的,没关系。设想一棵树,其中兄弟姐妹共享对父级的引用。这种情况很常见。

简单的回答是没问题

较长的答案(暂时忘记MVC,因为MVC似乎是这样做的一个例子,而不是问题的核心)是您必须考虑可变性。如果一个对象是不可变的(对象上的任何字段都不能更改),那么共享是一件非常好的事情,它可以减少内存占用,并且没有真正的缺点

但是,如果对象是可变的,那么您必须了解更改对象的状态如何影响引用它的对象。在MVC中,看到模型的改变是非常典型的,然后最终基于此调整视图,因此您可以将其构建到设计中,但是考虑到这种情况:

  private Collection myCollection; 

  public void setMyCollection(Collection someCollection) { 
       myCollection = someCollection; 
  }
这样的代码必须非常有信心,调用方不会向它传递一个随后更改的可变集合,否则它必须允许这样做。解决上述问题的典型方法是复制(
myCollection=newarraylist(someCollection);


总之,这是一种很好的常见做法,但是当对象是可变的时,您必须仔细考虑对设计的影响。

简单的回答是,这很好

较长的答案(暂时忘记MVC,因为MVC似乎是这样做的一个例子,而不是问题的核心)是您必须考虑可变性。如果对象是不可变的(t上没有字段
class View {
   public Model m; 
}
class Controller {
    public Model m;  
}
....
public static void main( String ... args ) { 
     Model m = ... 
     View v = new View();
     Controller c = new Controller();
     v.m = m;
     c.m = m;
}