我对一个结构有一个具体的想法,但我无法确定这方面的模式。所以我想我做了一些我应该避免的事情,并以不同的方式去做。
我的应用程序将控制具有多个通信接口和多个传感器的多个设备(都是相同类型的)(这是一个演示概念的简化示例!)。
下面,您可以找到示例代码。现在,让我们只关注“设备”类。这是一种介于中间的人,它不提供任何自己的功能,而只实现其他类。
这听起来像个“正面”。但不同之处在于,facade将其他类嵌入为私有实例并提供函数,在我的示例中,我将实现的实例声明为公共实例,让用户直接访问它们。
成就:“设备”提供的服务的数量(在我的实际案例中是很高的)被分割成特定的主题。"CommunicationServices“和"MeasurementServices")这将有助于用户获得比代码更好的方向。
那么,下面是否有表示此实现的模式(我根本无法识别)?还是仍然被称为“正面”?
class Application()
{
List<IDevice> _listOfDevices = new List<IDevice>;
readonly Device.Factory _deviceFactory;
Application(Device.Factory df)
{
_deviceFactory = df;
}
void DoSomething()
{
// e.g. instantiate 2 devices
_listOfDevices.Add(_deviceFactory);
_listOfDevices.Add(_deviceFactory);
foreach(IDevice device in _listOfDevices)
{
int temperature = device.MeasurementServices.TemperatureSensor.ReadTemperature();
device.CommunicationServices.Wifi.SendMessage(temperature);
//... and so on
}
}
}
public class Device : IDevice
{
public delegate Device Factory();
public ICommunicationServices CommunicationServices { get; }
public IMeasurementServices MeasurementServices { get; }
public Device (ICommunicationServices comServices, IMeasurementServices measurementServices)
{
CommunicationServices = comServices;
MeasurementServices = measurementServices;
}
}
public class CommunicationServices : ICommunicationServices
{
IBluetooth Bluetooth { get; }
IWifi Wifi { get; }
ISerial Serial { get; }
// ... more interfaces
public CommunicationServices(IBluetooth bt, IWifi wf, ISerial sr)
{
Bluetooth = bt;
Wifi = wf;
Serial = sr;
}
}
public class MeasurementServices : IMeasurementServices
{
ITemperatureSensor TemperatureSensor { get; }
IHumiditySensor HumiditySensor { get; }
// ... more sensors
public MeasurementServices (ITemperatureSensor ts, IHumiditySensor hs)
{
TemperatureSensor = ts;
HumiditySensor = hs;
}
}接收到第一个输入后添加的:
马克写道:“对你来说有意义的等级结构可能不符合其他人的思维模式。”
这总是个问题,想在数据服务器上建立一个每个人都满意的数据结构是不可能的。
因此,另一种方法是为设备接口中的每个设备数据定义一个访问器?例如:
// Interface that is going to have a huge number of accessors...
public interface IDevice
{
string Device.GetSsid();
void Device.SetSsid(string ssid);
int Device.GetLoggerInterval();
void Device.SetLoggerInterval(int interval_ms);
// ...
}在多数派中讲话
我所关注的问题就在这个例子中:两个数据"SSID“和"Interval”是非常不同的主题,但它们会出现在一起。这也不能使学习代码变得容易。
或者还有什么其他的方法来面对这个问题--“火车故障”和“单一的巨大界面”?也许两者兼而有之(这将是一个不合理的解决方案)?
发布于 2021-04-18 07:25:47
即使您对代码的结构有一个清晰的愿景,它也不必是一个设计模式。有些代码只是代码,而一些常见的代码结构则是反模式(或代码气味)而不是模式。

我同意这看起来不像个门面。如果有的话,它看起来更像一个列车残骸 -一种代码气味。火车残骸违反了德米特定律。然而,这项“法律”是有争议的:
"我希望它被称为德米特偶尔有用的建议。“ -马丁·福勒
多年来,我越来越多地同意马丁·福勒的观点,即这条“法律”可能并不完全是这样。然而,OP询问建议的设计是否适合特定的设计模式。我不认为它有,但我冒昧地扩展了这个主题,也包括了各种命名的设计原则。
无论你是否认为“德米特定律”是一项适当的设计原则,我要质疑的是,拟议的设计是否符合规定的目标:
这将有助于用户获得比代码更好的方向。
我想说的是,事实恰恰相反。这种设计使得学习和使用代码变得更加困难。
这个问题是关于C#代码的,大多数C#开发人员与陌生库交互的方式是通过IntelliSense进行的。给定一个类型为Device的对象Device,他们通常会在device之后键入一个点(.),以查看他们有哪些选项。IntelliSense将给他们一个GUI (一个高级下拉控件)来枚举Device的实例成员。(菲尔特雷福德这个点驱动的开发)。
因此,如果您键入device. (请注意尾随点),您将得到一个其他对象的列表:
CommunicationServicesMeasurementServices当你点缀在一个对象中时,你通常是在寻找某种行为--一种需要调用的方法。子对象中没有一个是方法,因此基本上可以保证第一个点不会产生有用的成员。
用户将不得不“点到”其中一个子对象,以查看他们正在寻找的行为是否存在。例如,他们可能会在CommunicationServices中输入“点入”,然后键入另一个点,以查看他们正在寻找的行为是否应该挂起。如果没有,则必须删除IDE为其创建的CommunicationServices属性访问权限,并尝试下一个访问。
我曾经使用过类似的API,我知道它们应该是有用的,但它们没有--它们令人恼火。
你应该小心引入等级制度来帮助人们。很少有一种方法可以将给定的问题域建模为层次结构,而对您来说有意义的层次结构可能不适合其他人所拥有的心理模型。
用户可以直接在Device上显示所有成员,这样程序员只需要“点”一次就更有帮助了。
如果您觉得Device上的成员太多了,这可能是另一种代码味道,但我无法从OP中看出这一点。
https://stackoverflow.com/questions/67123743
复制相似问题