gpt4 book ai didi

oop - 将模型与其表示分离的面向对象的方法

转载 作者:行者123 更新时间:2023-12-04 15:16:37 25 4
gpt4 key购买 nike

假设我们有一个表示硬件配置的对象。为了论证起见,一个温度 Controller (TempController)。它包含一个属性,即设定点温度。

我需要将此配置保存到文件中以在其他设备中使用。文件格式 (FormatA) 是一成不变的。我不希望 TempController 对象知道文件格式......它与该对象无关。所以我创建了另一个对象“FormatAExporter”,它将 TempController 转换为所需的输出。

一年后,我们制作了一个新的温度 Controller ,我们称之为“AdvancedTempController”,它不仅有一个设定点,而且还有速率控制,这意味着还有一两个属性。还发明了一种新的文件格式来存储这些属性……我们称之为 FormatB。

两种文件格式都能够表示两种设备(假设 AdvancedTempController 如果缺少设置则具有合理的默认值)。

所以这里的问题是:不使用“isa”或其他一些“作弊”方式来确定我拥有什么类型的对象,FormatBExporter 如何处理这两种情况?

我的第一直觉是在每个温度 Controller 中都有一个可以为该类提供客户导出器的方法,例如 TempController.getExporter() 和 AdvancedTempController.getExporter()。这不能很好地支持多种文件格式。

唯一想到的其他方法是在每个温度 Controller 中都有一个方法,该方法返回属性及其值的列表,然后格式化程序可以决定如何输出这些。它会起作用,但这似乎令人费解。

更新:在进一步的工作中,后一种方法并不能很好地工作。如果您的所有类型都很简单,那么它可能是简单的,但是如果您的属性是对象,那么您最终只会将问题推向下一个级别……您被迫返回一对 String,Object 值,并且导出器必须知道是什么对象实际上是为了使用它们。所以它只是把问题推到了另一个层次。

有什么建议可以让我保持这种灵活性吗?

最佳答案

您可以做的是让 TempControllers 负责使用通用归档程序保持自身。

class TempController 
{
private Temperature _setPoint;
public Temperature SetPoint { get; set;}

public ImportFrom(Archive archive)
{
SetPoint = archive.Read("SetPoint");
}
public ExportTo(Archive archive)

{
archive.Write("SetPoint", SetPoint);
}
}

class AdvancedTempController
{
private Temperature _setPoint;
private Rate _rateControl;
public Temperature SetPoint { get; set;}
public Rate RateControl { get; set;}

public ImportFrom(Archive archive)
{
SetPoint = archive.Read("SetPoint");
RateControl = archive.ReadWithDefault("RateControl", Rate.Zero);
}

public ExportTo(Archive archive)
{
archive.Write("SetPoint", SetPoint);
archive.Write("RateControl", RateControl);
}
}

通过保持这种方式, Controller 不关心实际值是如何存储的,但您仍然可以很好地封装对象的内部。

现在您可以定义一个所有归档类都可以实现的抽象归档类。
abstract class Archive
{
public abstract object Read(string key);
public abstract object ReadWithDefault(string key, object defaultValue);
public abstract void Write(string key);
}

FormatA 存档器可以采用一种方式,而 FormatB 存档器可以采用另一种方式。
class FormatAArchive : Archive
{
public object Read(string key)
{
// read stuff
}

public object ReadWithDefault(string key, object defaultValue)
{
// if store contains key, read stuff
// else return default value
}

public void Write(string key)
{
// write stuff
}
}

class FormatBArchive : Archive
{
public object Read(string key)
{
// read stuff
}

public object ReadWithDefault(string key, object defaultValue)
{
// if store contains key, read stuff
// else return default value
}

public void Write(string key)
{
// write stuff
}
}

您可以添加另一个 Controller 类型并将其传递给任何格式化程序。您还可以创建另一个格式化程序并将其传递给任何 Controller 。

关于oop - 将模型与其表示分离的面向对象的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1096201/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com