私有实例可以在对象之间共享吗?
我只允许在我正在学习的编程课程中使用私有成员,我想知道这样的事情是否可以。
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
}
}
View 和 Controller 类都将相同的 Model 实例作为私有字段保存。这是可以接受的吗?看起来这违反了私有字段的概念。我试着问我的教授,他说没关系,但我不确定他是否理解我的问题,或者我是否理解他的答案:)
I am only allowed to use private members in the programming course I'm taking, and I was wondering if something like this is ok.
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
}
}
The View and Controller classes both hold the same instance of the Model as private fields. Is this acceptable? It seems like it would violate the concept of private fields. I tried asking my professor, and he said it was ok, but I'm not sure if he understood my question, or if I understood his answer :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
关于标题问题:是的,没关系。想象一棵树,其中兄弟姐妹共享对父级的引用。这种情况很常见。
Regarding the title question: yes, it's ok. Think of a tree where siblings share the reference to a parent. This situation is quite common.
是的。
事实并非如此。控制器无法从视图中更改实例,因为它是私有的。
考虑以下尝试更改视图中模型的代码行:
这行不通,第一,因为模型没有对视图的引用,第二, >nd,如果有的话,
controller
无法更改视图中的model
,因为它对他来说是不可见的。在某些情况下共享同一个对象可能并不理想。例如,如果您依赖给定对象的状态,并且该状态被其他对象更改,则您的代码可能会失败。请参阅防御性复制 这就是为什么建议使用不可变对象并限制对它的访问。
但特别是在 MVC 设计模式中,共享正是您所需要的对象,或者至少共享该对象的状态。在 MVC 中,您需要的是
View
和Controller
来了解Model
状态。看到同一个对象并不会使它们的私密性降低(从某种意义上说,每个对象都不知道它们看到的是相同的东西),这允许 低耦合肯定会破坏对象隐私的属性将具有非私有属性,如下所示:
因为不会有任何访问控制来阻止发生疯狂的更改。
Yes it is.
It doesn't. The controller cannot change the instance from the view, because it it private.
Consider the following line of code that attempt to change the model in the view:
Well this won't work, 1st because, the model doesn't have a reference to the view, and 2nd, if it had it, the
controller
can't change themodel
in the view, because it is invisible to him.Sharing the same object may not be desirable in some situations. For instance if you rely on the state of a given object and that state is change by other object, your code may fail. See Defensive Copying That's why it is recommended to use immutable objects and restrict the access to it.
But particularly in the MVC design pattern sharing an object that's exactly what you need, or at least sharing the state of that object. In MVC what you need is the
View
and theController
to be aware of theModel
state. Seeing the same object doesn't make them less private ( in the sense that neither of each objects know they are seeing the same thing ) this allows Low CouplingWhat would definitely ruin object privacy would have that attribute as non private as:
Because there won't be any access control that prevents from wild changes to occur.
如果您查看这篇文章,您将看到理想情况下控制器位于模型和视图之间。因此,我也许会稍微重新组织您的依赖项(对此存在一些分歧 - 见下文)
但是您问题的答案(无论域如何)是您可以共享这些周围的私人参考。理想情况下,它们应该是对接口的引用,并且可以在不更改依赖类的情况下更改实现。因此(例如)您将拥有一个
Model
接口和一个实现ModelImpl
,并且共享引用的类型为Model
。然后,您可以在以后替换不同的实现,而不会影响大部分代码。If you look at this article, you'll see that ideally the controller sits between the model and view. So I would perhaps reorganise your dependencies somewhat (there's some disagreement about this - see below)
But the answer to your question (regardless of the domain) is that you can share these private references around. Ideally they should be references to interfaces, and the implementations can change without changing the dependent classes. So (for example) you would have a
Model
interface, and an implementationModelImpl
, and the shared references would be of typeModel
. You can then substitute different implementations at a later date without affecting the majority of your code.简短的回答是,没问题。
较长的答案(暂时忘记 MVC,因为 MVC 似乎是这样做的一个示例,而不是问题的核心)是您必须考虑可变性。如果一个对象不是可变的(对象上的任何字段都不能更改),那么共享是一件非常好的事情,它减少了内存占用并且没有真正的缺点。
但是,如果对象是可变的,那么您必须了解更改对象的状态如何影响引用它的对象。在 MVC 中,看到模型发生变化,然后根据该模型最终调整视图是非常典型的,因此您可以将其构建到设计中,但请考虑这种情况:
这样的代码必须非常有信心调用者不会通过它是一个可变集合,之后会发生变化,或者它必须允许这种情况。解决上述情况中的问题的典型方法是制作一个副本 (
myCollection = new ArrayList(someCollection);
)总而言之,这是一种常见的做法,很好,但是当对象是可变的,你必须考虑对你的设计的影响。
The short answer is that it is fine.
The longer answer (forgetting about MVC for a second, because it seems that MVC is an example of doing it, not the core of the question) is you have to think about mutability. If an object is not mutable (none of the fields on the object can ever change) then sharing is a very good thing, it reduces memory footprint and has no real downside.
If, however the object is mutable, then you have to understand how changing the state of the object affects those that reference it. In MVC it is pretty typical to see the model changed and then have the view ultimately adjusted based on that, so you would build that into the design, but consider this case:
Such code has to be very confident that the caller won't pass it a mutable collection that gets changed afterward, or it has to allow for that. The typical way around the problem in the above case is to make a copy (
myCollection = new ArrayList(someCollection);
)So to sum up, it is a common practice that is fine, but when the object is mutable, you have to think through the consequences on your design.
简短回答:
两个不同的类具有引用相同事物的私有成员变量,这没有任何问题。这很常见。
长答案:
我的猜测是,你的教授可能在这里谈论的是:
private Model object_
是一个对象引用变量(不是基元)。因此,当您将object_
传递到 Controller 和 View 的构造函数时,您将传递一个“链接”到的同一个实例
object_
,而不是传递object_
的副本。是否选择在 Controller 和 View 中将它们存储为私有是一个完全不同的决定。我熟悉大学编程课程禁止使用非私有成员变量(去过那里)。他们想介绍一些面向对象的概念,例如封装(稍后),然后他们会告诉您为私有成员变量创建公共访问器和修改器。这通常是一个很好的开始原则,因为只有在有充分理由时才应使用受保护和公共成员变量。
所以,是的,这些是正确的 Java,但是这是否真的是您想要对代码执行的操作则是另一回事(请参阅 Caleb 的回答)。
Short answer:
There isn't anything wrong with two different classes which have private member variables that reference the same thing. It is quite common.
Long Answer:
My guess is that what your professor may have been talking about here is:
private Model object_
is an object reference variable (not a primitive). So when you passobject_
into the constructors of Controller and View, you are passing a "link" to the same instance ofobject_
, instead of passing a copy ofobject_
.Whether or not you choose to store them as private in Controller and View is a completely different decision. I am familiar with university programming courses forbidding the use of non-private member variables (been there). They want to introduce some Object Oriented concepts, such as encapsulation (later), they will then tell you to create public accessors and mutators for the private member variables. This is generally be a good principle to start with, as protected and public member variables should only be used when you have a good reason to do so.
So yes, these is correct Java, but whether or not this actually what you want to do with your code is another matter (see Caleb's answer).
是的,这是可以接受的,应该使用私有字段来强制封装,如果需要,可以通过 getter/setter 方法控制对这些字段的访问。如果这些字段是公共的甚至是打包的,那么外部类可能开始依赖于您对该类的实现,这会在重构方法等方面束缚您。允许其他类访问它们不应该访问的字段可能会导致隐私泄漏。
如果模型公开。
班级混乱
{
模型 aModel = object_;
aModel.doWhatTheHellIWantToYourModel();
这
可以完全验证系统的状态。
Yes, this is acceptable, private fields should be used to enforce encapsulation, by controllingb access to these field through getter/ setter methods if required. if these fields where public or even package then outside classes may start to depend upon you implementation of the class, which ties you down in terms of refactoring methods etc. Allowing other classes access to fields they shouldny have access to can provide a privacy leak.
If model where public.
Class messUp
{
Model aModel = object_;
aModel.doWhatTheHellIWantToYourModel();
}
this could completely ivalidate the state of your system.
据我所知,没有硬性规定的“私有领域法则”规定一件物品可以被多个阶级私有。对于像不可变引用类这样的东西,多个类实例可以接收不可变引用类并将其作为私有属性保存是有意义的。
在你的例子中,卡尔是对的——视图和控制器通常应该在某种方法中将模型作为参数,而不是保留对它们的引用。所以代码看起来更像是这样的:
As far as I know, there's no hard and fast "law of private fields" that says that an object can be held privately by more than one class. For something like an immutable reference class, it makes sense that multiple class instances could receive the immutable reference class and hold it as a private attribute.
In your example, Carl is right -- Views and Controllers should generally take a Model as a parameter in some method, not keep a reference to them. So the code would look more like this: