简体   繁体   中英

Which design pattern to use for Step wise object update

I have to write a logic that would update an Object through a series of methods and would detect what step has failed :

EntryPointForLogic() {
    Object obj = CreateObject();

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

Is there a preferred / standard design pattern for writing similar logic. The different steps could fail and I want to detect which one of them failed.

This roughly maps to something like a chain of responsibility , you could use an abstract class along with step name information and logging to create an audit trail.

Again, this is not exactly a chain of responsibility because the previous handler is not changing the steps in my example

Abstract class

This is not perfect, you'll need to handle the implementation of stuff as you need it, and wouldn't recommend building your own logging library but still an OK example

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

Example Implementation

Then you just define the individual updaters, for example

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

Actual Chain

You can just create an enumerable with all of the different implementations of your Updaters and apply them in order

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

Further reading

If you want to read more about the pattern you can see the links provided below

You can use List of Action and Iterate through them:

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

To add name of each action you can use

- inside method : List<Tuple<string,Action<object>>>
- in interface you should not expose Tuple so create your own class/struct with name and action.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM