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

本文关键字:设计模式 对象 更新 用于 | 更新日期: 2023-09-27 17:57:52

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

EntryPointForLogic() {
    Object obj = CreateObject();
    UpdateObj1(obj);
    UpdateObj2(obj);
    ....
    UpdateObj_(obj);
}

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

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

这大致映射到之类的东西一个责任链,您可以使用一个抽象类以及步骤名称信息和日志来创建审计跟踪。

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

抽象类

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

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;
      }
}

实际链

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

//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);
    }
}

进一步阅读

如果你想阅读更多关于模式的信息,你可以看到下面提供的链接

  • 责任链模式,维基百科
  • 责任链模式教程,Java示例,DZone

您可以使用操作列表并遍历它们:

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>>>
-在接口中,您不应该公开Tuple,所以创建您自己的带有名称和操作的类/结构。