适合我的案例的基于 MVC 的 OOP 设计是什么?
What is an appropriate MVC-based OOP design for my case?
假设以下基准设计:我有一个 class CarElement
,它包含与汽车的视觉表示和数据 model/logic 表示相关的属性和方法:
class carElement
{
// UI related properties and methods:
public Size DrawSize { get; set; }
public Point Location { get; set; }
public void Draw()
{
// do something...
}
// data model / logic related properties and methods:
public double weight { get; set; }
public string manufacturer { get; set; }
public double CalculatePrice()
{
// do something...
return 0;
}
}
这个class的用法如下:carElement
的多个实例被绘制到一些canvas。单击每辆绘制的汽车会使用 propertygrid.SelectedObject = InstanceOfcarElement
.
在 属性 网格中显示该汽车的属性
在我看来,这种设计是有缺陷的,因为数据模型和视觉表示在 class 设计中没有分开。我想改进 MVC 的设计,我正在寻求有关良好设计决策的建议。
我目前对此的看法是将上面的 class carElement
分成类似下面两个 class 的内容。
class carUIElement // organizes visual representation of a car
{
public Size DrawSize { get; set; }
public Point Location { get; set; }
private carDataElement linkedCarDataElement;
public void Draw()
{
// do something...
}
}
class carDataElement // organizes data model organization of a car
{
public double weight { get; set; }
public string manufacturer { get; set; }
private carUIElement linkedCarUIElement;
public double CalculatePrice()
{
// do something...
return 0;
}
}
使用这种方法,我不清楚以下内容:
carUIElement
应该知道它链接到的 carDataElement
,反之亦然。有没有比上面代码中的简单链接更好的设计方法?
- 当绘制的 UI 元素是点击了吗?
整体方法是否可行?上面的开放点呢?我缺少判断的经验,所以我将感谢您的评论。谢谢。
虽然我们应该始终注意不要过度智能化东西,毕竟我们作为程序员比艺术家更多的是石匠,即使巴黎圣母院只是建筑而不是艺术,也不总是需要ui红色夸张的装饰和音响室,估计下个版本会像上个一样宏伟:)
我是什么意思?我建议使用 MVC 的实用主义,所以如果并且如果在程序的初期阶段,它可以具有 ui 模型,有时也称为数据传输对象,与逻辑模型相同,这本身并不反-模式imo。
显然,一旦构建 ui,我们就开始发布具有假定结构的实例,当它开始限制产品的开发时,它的呈现方式,通常是当您需要比 ui 相关的更多信息时,存储在实体上,然后您可以通过发明 DTO 模型对象和参与初始模型来锁定接口。
所以我知道你要去的地方以及你可能想要将它分开的原因。
然后我们又经常有 web 前端,尤其是 mvc,然后大多数情况下它将不再是数据绑定视图,而是像 Angular、React、Vue 甚至 Blazor 这样的 MVVM 东西,如果出于某种原因您可能想要那个,或者传统的 Razor 页面,真的吗?在新的发展??
我尽量不在 DTO classes 中放置任何内容,如果只有序列化的 JSON 版本可用于您的视图引擎,这些内容就会丢失。因此,当发生现代化时,您的控制器/ api 不必进行主要更改。
所以单独 classes 是为了单独关注数据访问或传输中没有逻辑 classes,我的建议是按照以下几行,但以你的问题结尾:
a) 如果您使用它来加载数据模型中的导航 属性,则链接是有意义的,例如使用 entity framework,它是 required。
在你的 UI 类型中,频率是关键,通常我们喜欢将所有数据推送到点中,这样它们就不需要执行任何其他操作,但是如果 class 正在被序列化和反序列化并且你使用像 AutoMapper 这样的工具来回移动,如果你在像 WPF 这样的 windows 客户端中嘿你的模型已经在客户端上并且已经为 MVVM 加载了,你在这样一个更好的地方你可能并不真正关心前端类型,直到它们需要改变。
b) 问题是你是一直想显示两者还是隐藏 cardata 元素直到他们要求它,这将决定让 DTO 包含关系数据或仅包含外部数据的选择键并有一个额外的查找方法可用 imo。
所以建议简述:
/// <summary>
/// Drawing is a separate concern of the application
/// </summary>
class DrawManager
{
public void DrawCar(CarBase car) { }
}
/// <summary>
/// So is calculating prices
/// </summary>
class PriceManager
{
decimal CalculateCarPrice(CarBase car) { throw new NotImplementedException(); }
}
/// <summary>
/// The 2 classes share properties, invent a base class to abide by the DRY principle
/// </summary>
class CarBase
{
public Size DrawSize { get; set; }
public Point Location { get; set; }
}
/// <summary>
/// Now they are identical
/// </summary>
class carElement : CarBase
{
carDataElement CarData { get; set; }
}
/// <summary>
/// Now they are identical
/// </summary>
class carUIElement : CarBase
{
carDataElement linkedCarDataElement;
}
/// <summary>
/// The data about a car, in RDBMS typically normalized into a seperate entity like you have,
/// does UI really need any of them? Is it always needed when other members are accessed?
/// </summary>
/// <remarks>
/// we could choose to have the data model have a navigation property and then let the ui member not have it and give it a method to ackquire it,
/// but then that shouldn't get done to early and well if it always needs it, it is not yet a seperate datatype justification for the ui aspect
/// </remarks>
class carDataElement
{
public double weight { get; set; }
public string manufacturer { get; set; }
}
假设以下基准设计:我有一个 class CarElement
,它包含与汽车的视觉表示和数据 model/logic 表示相关的属性和方法:
class carElement
{
// UI related properties and methods:
public Size DrawSize { get; set; }
public Point Location { get; set; }
public void Draw()
{
// do something...
}
// data model / logic related properties and methods:
public double weight { get; set; }
public string manufacturer { get; set; }
public double CalculatePrice()
{
// do something...
return 0;
}
}
这个class的用法如下:carElement
的多个实例被绘制到一些canvas。单击每辆绘制的汽车会使用 propertygrid.SelectedObject = InstanceOfcarElement
.
在我看来,这种设计是有缺陷的,因为数据模型和视觉表示在 class 设计中没有分开。我想改进 MVC 的设计,我正在寻求有关良好设计决策的建议。
我目前对此的看法是将上面的 class carElement
分成类似下面两个 class 的内容。
class carUIElement // organizes visual representation of a car
{
public Size DrawSize { get; set; }
public Point Location { get; set; }
private carDataElement linkedCarDataElement;
public void Draw()
{
// do something...
}
}
class carDataElement // organizes data model organization of a car
{
public double weight { get; set; }
public string manufacturer { get; set; }
private carUIElement linkedCarUIElement;
public double CalculatePrice()
{
// do something...
return 0;
}
}
使用这种方法,我不清楚以下内容:
carUIElement
应该知道它链接到的carDataElement
,反之亦然。有没有比上面代码中的简单链接更好的设计方法?- 当绘制的 UI 元素是点击了吗?
整体方法是否可行?上面的开放点呢?我缺少判断的经验,所以我将感谢您的评论。谢谢。
虽然我们应该始终注意不要过度智能化东西,毕竟我们作为程序员比艺术家更多的是石匠,即使巴黎圣母院只是建筑而不是艺术,也不总是需要ui红色夸张的装饰和音响室,估计下个版本会像上个一样宏伟:)
我是什么意思?我建议使用 MVC 的实用主义,所以如果并且如果在程序的初期阶段,它可以具有 ui 模型,有时也称为数据传输对象,与逻辑模型相同,这本身并不反-模式imo。 显然,一旦构建 ui,我们就开始发布具有假定结构的实例,当它开始限制产品的开发时,它的呈现方式,通常是当您需要比 ui 相关的更多信息时,存储在实体上,然后您可以通过发明 DTO 模型对象和参与初始模型来锁定接口。 所以我知道你要去的地方以及你可能想要将它分开的原因。
然后我们又经常有 web 前端,尤其是 mvc,然后大多数情况下它将不再是数据绑定视图,而是像 Angular、React、Vue 甚至 Blazor 这样的 MVVM 东西,如果出于某种原因您可能想要那个,或者传统的 Razor 页面,真的吗?在新的发展?? 我尽量不在 DTO classes 中放置任何内容,如果只有序列化的 JSON 版本可用于您的视图引擎,这些内容就会丢失。因此,当发生现代化时,您的控制器/ api 不必进行主要更改。
所以单独 classes 是为了单独关注数据访问或传输中没有逻辑 classes,我的建议是按照以下几行,但以你的问题结尾:
a) 如果您使用它来加载数据模型中的导航 属性,则链接是有意义的,例如使用 entity framework,它是 required。 在你的 UI 类型中,频率是关键,通常我们喜欢将所有数据推送到点中,这样它们就不需要执行任何其他操作,但是如果 class 正在被序列化和反序列化并且你使用像 AutoMapper 这样的工具来回移动,如果你在像 WPF 这样的 windows 客户端中嘿你的模型已经在客户端上并且已经为 MVVM 加载了,你在这样一个更好的地方你可能并不真正关心前端类型,直到它们需要改变。
b) 问题是你是一直想显示两者还是隐藏 cardata 元素直到他们要求它,这将决定让 DTO 包含关系数据或仅包含外部数据的选择键并有一个额外的查找方法可用 imo。
所以建议简述:
/// <summary>
/// Drawing is a separate concern of the application
/// </summary>
class DrawManager
{
public void DrawCar(CarBase car) { }
}
/// <summary>
/// So is calculating prices
/// </summary>
class PriceManager
{
decimal CalculateCarPrice(CarBase car) { throw new NotImplementedException(); }
}
/// <summary>
/// The 2 classes share properties, invent a base class to abide by the DRY principle
/// </summary>
class CarBase
{
public Size DrawSize { get; set; }
public Point Location { get; set; }
}
/// <summary>
/// Now they are identical
/// </summary>
class carElement : CarBase
{
carDataElement CarData { get; set; }
}
/// <summary>
/// Now they are identical
/// </summary>
class carUIElement : CarBase
{
carDataElement linkedCarDataElement;
}
/// <summary>
/// The data about a car, in RDBMS typically normalized into a seperate entity like you have,
/// does UI really need any of them? Is it always needed when other members are accessed?
/// </summary>
/// <remarks>
/// we could choose to have the data model have a navigation property and then let the ui member not have it and give it a method to ackquire it,
/// but then that shouldn't get done to early and well if it always needs it, it is not yet a seperate datatype justification for the ui aspect
/// </remarks>
class carDataElement
{
public double weight { get; set; }
public string manufacturer { get; set; }
}