哪种设计模式用于逐步对象更新

时间:2016-07-20 21:58:16

标签: c# design-patterns

我必须编写一个逻辑,通过一系列方法更新Object,并检测哪个步骤失败了:

EntryPointForLogic() {
    Object obj = CreateObject();

    UpdateObj1(obj);
    UpdateObj2(obj);
    ....
    UpdateObj_(obj);
}

是否有用于编写类似逻辑的首选/标准设计模式。 不同的步骤可能会失败,我想检测其中哪一个失败。

2 个答案:

答案 0 :(得分:2)

这大致映射到 之类的 责任链,您可以使用抽象类以及步骤名称信息并记录创建审计跟踪。

同样,这不是一个责任链因为前一个处理程序没有改变我的示例中的步骤

抽象类

这不是完美的,您需要根据需要处理内容的实现,并且不建议构建自己的日志库,但仍然是一个好例子

public abstract class Updater<T> 
{
     private readonly ILog _logger;
     public Name {get; private set;}
     public Updater(string name, ILog logger)
     {
         _logger= logger;
         Name = name;
     }


     protected abstract UpdateImpl(T updating);

     public Update(T updating)
     {
         _logger.Log("Started updater " + Name);
         try
         {
             UpdateImpl(updating);
         }
         //DON'T DO THIS IN ACTUAL IMPLEMENTATION
         //DO NOT EAT ALL OF THE EXCEPTIONS
         catch ( Exception e)
         {
            _logger.Log(e);   
         }
         finally
         {
             _logger.Log("Finished Updater " + Name);
         }
     }
}

实施示例

然后您只需定义各个更新程序,例如

public class AwesomeObjectNameUpdater : Updater<AwesomeObject>
{
      public AwesomeObjectNameUpdater(ILogger logger) :base("Awesome Name Updater", logger)
      {

      }

      protected override UpdateImpl(AwesomeObject updating)
      {
           //here your mission critical business logic will go
           updating.Name = "Mr.Fancy-Pants " + updating.Name;
      }
}

实际链

您可以使用Updaters的所有不同实现创建一个枚举,并按顺序应用它们

//assume it is assign in a constructor
private readonly IEnumerable<Updater<AwesomeObject>> _updaters;
public void ApplyUpdaters(AwesomeObject obj)
{
    foreach(var updater in _updaters)
    {
        updater.Update(obj);
    }
}

进一步阅读

如果您想了解有关该模式的更多信息,请参阅下面提供的链接

答案 1 :(得分:1)

您可以使用动作列表并通过它们进行迭代:

EntryPointForLogic() {
    Object obj = CreateObject();
    List<Action<object>> actions = new List<Action<object>>()
    { 
         UpdateObj1,UpdateObj2,UpdateObj3
    };


    for(int i =0; i<actions.Count; i++)
    {
        try
        {
             actions[i](obj);
        }
        catch(Exception ex)
        {
            Console.WriteLine($"Error occured in update nr {i}");
        }
    }
}

添加您可以使用的每个操作的名称

- 内部方法:List<Tuple<string,Action<object>>>
- 在界面中你不应该暴露元组,所以用名称和动作创建你自己的类/结构。