首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >设计模式问题/违反OCP

设计模式问题/违反OCP
EN

Code Review用户
提问于 2013-04-22 17:03:57
回答 2查看 202关注 0票数 3

是否有一个设计模式,我可以使用在以下情况。这是我编造的一个例子,试图解释我目前正在处理的情况。当情况出现时,我不得不向我的DeviceScript中添加新的DeviceAnalyzer类,并在“GetScriptForDevice”中添加关于何时返回新类型的逻辑。

我给出的这个例子非常简单,但是我必须为我真正的'GetScriptForDevice‘实现的业务逻辑并不总是那么简单。任何关于模式或更好地构造代码以遵循更好模式的示例的建议都将受到极大的赞赏。每次我需要添加一个新的DeviceScript时,我都违反了OCP,并且我试图找到一种解决这个问题的方法,因为我的课变得非常长,很脆弱。

谢谢。

代码语言:javascript
复制
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;
     }

}
EN

回答 2

Code Review用户

回答已采纳

发布于 2013-04-22 23:17:54

我建议诸如此类的

代码语言:javascript
复制
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信任:)

进一步的建议:

  1. 在计算完deviceScripts枚举之后,您可以将其存储在某个静态字段中以供进一步使用。
  2. 如果代码中不需要名称属性,则可以将IDeviceScript的Name属性移到DeviceScriptAttribute中。
  3. 我会使GetScriptForDevice方法是静态的,但不幸的是,.net不支持接口中的静力学:
票数 4
EN

Code Review用户

发布于 2013-04-23 17:26:34

基于@user1614543's的答案,您可以创建一个更通用的IDeviceScript实现:

代码语言:javascript
复制
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等)填充可用设备脚本列表。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/25345

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档