是否有一个设计模式,我可以使用在以下情况。这是我编造的一个例子,试图解释我目前正在处理的情况。当情况出现时,我不得不向我的DeviceScript中添加新的DeviceAnalyzer类,并在“GetScriptForDevice”中添加关于何时返回新类型的逻辑。
我给出的这个例子非常简单,但是我必须为我真正的'GetScriptForDevice‘实现的业务逻辑并不总是那么简单。任何关于模式或更好地构造代码以遵循更好模式的示例的建议都将受到极大的赞赏。每次我需要添加一个新的DeviceScript时,我都违反了OCP,并且我试图找到一种解决这个问题的方法,因为我的课变得非常长,很脆弱。
谢谢。
public class DeviceScript {
public string Name { get; set; }
public string SecurityScriptName { get; set; }
public string BusinessScriptName { get; set; }
}
public class DeviceAnalyzer {
public const string US_SecurityScript = "US_SecurityScript";
public const string US_BusinessScript = "US_BusinessScript";
public const string UK_SecurityScript = "UK_SecurityScript";
public const string UK_BusinessScript = "UK_BusinessScript";
private DeviceScript UnitedStates = new DeviceScript {
Name = "US_Script",
SecurityScriptName = US_SecurityScript,
BusinessScriptName = US_BusinessScript
};
private DeviceScript UnitedKingdom = new DeviceScript {
Name = "UK_Script",
SecurityScriptName = UK_SecurityScript,
BusinessScriptName = UK_BusinessScript
};
public DeviceScript GetScriptForDevice(IDevice device) {
if(device.Location == Locations.US) {
return UnitedStates;
}
if(device.Location == Locations.UK) {
return UnitedKingdom;
}
return null;
}
}发布于 2013-04-22 23:17:54
我建议诸如此类的
public interface IDeviceScript
{
string Name { get; }
string SecurityScriptName { get; }
string BusinessScriptName { get; }
bool IsScriptApply(IDevice device);
}
public interface IDevice
{
Locations Location { get; }
// more methods and properties
}
[Serializable]
[AttributeUsage(AttributeTargets.Class)]
public class DeviceScriptAttribute : Attribute
{
}
[DeviceScript]
public class UnitedStatesScript : IDeviceScript
{
public string Name
{
get { return "US_Script"; }
}
public string SecurityScriptName
{
get { return "US_SecurityScript"; }
}
public string BusinessScriptName
{
get { return "US_BusinessScript"; }
}
public bool IsScriptApply(IDevice device)
{
return device.Location == Locations.US;
}
}
public IDeviceScript GetScriptForDevice(IDevice device)
{
IEnumerable<IDeviceScript> deviceScripts =
Assembly.GetExecutingAssembly()
.GetTypes()
.Where(t => t.GetCustomAttributes<DeviceScriptAttribute>().Any())
.Select(t => Activator.CreateInstance(t))
.Cast<IDeviceScript>();
foreach (IDeviceScript deviceScript in deviceScripts)
{
if (deviceScript.IsScriptApply(device))
{
return deviceScript;
}
}
return null;
}现在,只需向项目添加新的类,就可以添加更多的脚本。不需要xml信任:)
进一步的建议:
发布于 2013-04-23 17:26:34
基于@user1614543's的答案,您可以创建一个更通用的IDeviceScript实现:
public class DeviceScript : IDeviceScript
{
public DeviceScript (string name, string securityScriptName, string businessScriptName, Locations supportedLocation)
{
Name = name;
SecurityScriptName = securityScriptName;
BusinessScriptName = businessScriptName;
Location = supportedLocation;
}
public string Name { get; private set; }
public string SecurityScriptName { get; private set; }
public string BusinessScriptName { get; private set; }
public bool IsScriptApply (IDevice device)
{
return device.Location == Location;
}
private Locations Location { get; set; }
}您仍然可以使用他提出的访问者模式,但是这个替代的IDeviceScript实现将允许您通过一些配置源(平面文件、数据库、app.config等)填充可用设备脚本列表。
https://codereview.stackexchange.com/questions/25345
复制相似问题