Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/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
Oop MVC会破坏封装吗?_Oop_Model View Controller_Language Agnostic_Encapsulation - Fatal编程技术网

Oop MVC会破坏封装吗?

Oop MVC会破坏封装吗?,oop,model-view-controller,language-agnostic,encapsulation,Oop,Model View Controller,Language Agnostic,Encapsulation,比如说,我有一门课来模拟一座城市。其特点如下: 它只有两个属性“name”和“population”,它们都是私有的,在构造函数中设置 它有这些属性的getter,但没有setter 我不希望此类的任何用户设置属性,我希望它们使用public.edit()方法 此方法需要打开一个表单来输入城市和人口的新名称,即:视图。然后,如果我有一个视图,我想实现MVC模式,这样的想法是控制器接收.edit()调用,呈现视图,检索数据,并将其发送到视图,以便更改其状态 但是,如果我这样做,我必须将城市模式

比如说,我有一门课来模拟一座城市。其特点如下:

  • 它只有两个属性“name”和“population”,它们都是私有的,在构造函数中设置
  • 它有这些属性的getter,但没有setter
我不希望此类的任何用户设置属性,我希望它们使用public.edit()方法

此方法需要打开一个表单来输入城市和人口的新名称,即:视图。然后,如果我有一个视图,我想实现MVC模式,这样的想法是控制器接收.edit()调用,呈现视图,检索数据,并将其发送到视图,以便更改其状态

但是,如果我这样做,我必须将城市模式的属性从私人改为公共。因此,如果任何用户实例化我的类,她/他可以直接更改属性

那么,哲学问题是:这不是打破了封装

编辑只是为了使其更加明确:

city\u instance.edit()
方法应该是修改对象的唯一方法

此外,我发现我的部分问题来自于一种误解,即模型是一个对象(你可以在php mvc框架上看到这一点),当它实际上是一个不同的抽象时,它是一个对业务逻辑进行分组的层(域对象+我猜更多的东西)

免责声明:我真的不明白你在哪里提出要实现的
.edit()
方法,因此如果你能澄清一下这一点会有所帮助

第一个要考虑的问题是,在你的问题列表中,你似乎暗示了<代码>锡蒂<代码>实例就像一个不可变的对象:它在构造函数中取实例变量,而不允许任何外部变量来改变它们。但是,稍后您会声明您实际上想要创建一种可视化编辑

城市
实例的方法。这两个要求显然会造成一些紧张,因为它们是对立的

如果采用MVC方法,通过将视图与模型分离,您有两个主要选择:

  • 将您的
    城市
    对象视为不可变对象,在表单中更改值时,不要编辑实例,而是丢弃原始对象并创建新对象
  • 提供一种变异现有
    城市
    实例的方法

第一种方法如果你真的认为<代码>锡蒂<代码>是一个不可变的对象,那么保持你的模型完好无损。对于第二种方法,有许多不同的方法:

  • 最标准的方法是在
    City
    类中提供一个mutator。这可以是每个属性的独立设置器的形状,也可以是一条公共消息(我认为这是您提到的
    .edit()
    方法),通过获取一个数组一次更改多个属性。请注意,这里您不需要将表单对象作为参数,因为模型不应该知道视图。如果希望视图记录模型中的内部更改,可以使用模式
  • 对控制器使用“friend”类。有些语言允许友元类访问对象的内部。在这种情况下,您可以创建一个控制器,它是模型的一个朋友类,可以在模型和视图之间建立连接,而不必向模型中添加变体
  • 使用反射来完成类似于friend类的事情
这三种方法中的第一种是唯一的语言不可知论选择。这是否破坏了封装很难说,因为需求本身是相互冲突的(这基本上意味着希望将模型从视图中分离出来,用户可以对其进行更改,但不允许外部更改模型本身)。但是,我同意,如果您想要可变实例,将模型与视图分离有助于实现显式的变异机制

HTH

免责声明:我真的不明白您在哪里提出要实现的
.edit()
方法,因此如果您能稍微澄清一下,这会有所帮助

第一个要考虑的问题是,在你的问题列表中,你似乎暗示了<代码>锡蒂<代码>实例就像一个不可变的对象:它在构造函数中取实例变量,而不允许任何外部变量来改变它们。但是,稍后您会声明您实际上想要创建一种可视化编辑

城市
实例的方法。这两个要求显然会造成一些紧张,因为它们是对立的

如果采用MVC方法,通过将视图与模型分离,您有两个主要选择:

  • 将您的
    城市
    对象视为不可变对象,在表单中更改值时,不要编辑实例,而是丢弃原始对象并创建新对象
  • 提供一种变异现有
    城市
    实例的方法

第一种方法如果你真的认为<代码>锡蒂<代码>是一个不可变的对象,那么保持你的模型完好无损。对于第二种方法,有许多不同的方法:

  • 最标准的方法是在
    City
    类中提供一个mutator。这可以是每个属性的独立设置器的形状,也可以是一条公共消息(我认为这是您提到的
    .edit()
    方法),通过获取一个数组一次更改多个属性。请注意,这里您不需要将表单对象作为参数,因为模型不应该知道视图。如果希望视图记录模型中的内部更改,可以使用模式
  • 对控制器使用“friend”类。有些语言允许友元类访问对象的内部。在这种情况下,您可以创建一个控制器,它是您模型的一个朋友类,可以使c