1

My application has a scheduled (weekly) task to populate different attributes of an object. This application will be multi tenant which means, for each tenant, the application might have to populate different/subset attributes. To meet this requirement, I want to choose the right design pattern for my scheduled job. Two design patterns are under active consideration.

  1. Decorator
  2. Chain of responsibility

The main difference that I could find between these patterns is that, in the former the object gets pass through each class in the pipeline whereas in the latter only one class in the pipeline will act on the object.

For Decorator, I would create separate class for each attribute whereas for chain of responsibility, I would create separate class for each tenant. Is my understanding correct?

enter image description here

ps :: If my understanding is correct, I would prefer Decorator.

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
Winster
  • 943
  • 10
  • 28
  • 1
    Decorator does not sound correct imo. I'd use a Strategy Pattern here. Each job is an object, and each Job object has a Strategy for accomplishing that job. The Strategy is a separate object with the details of each job. Each job might have multiple strategies, if you can break down each task into discrete operations that any tenant might use. – markspace Apr 28 '21 at 15:07
  • 1
    Chain of Responsibility looks wrong to me as well. According to my Gang of Four book, CoR is "Avoid coupling the sender of a request to its receiver by giving more than one object a change to handle the request." This sounds more like a pipeline type of operation, which each job possibly being operated on by other objects. But the way you have it decomposed seems wrong for this pattern. I am however voting to close as opinion based. – markspace Apr 28 '21 at 15:10
  • related: [What is the difference between the CoR and the Decorator?](https://stackoverflow.com/q/61673275/1371329) – jaco0646 Apr 29 '21 at 00:28

2 Answers2

1

I agree with the @markspace comment that the Strategy Pattern appears to be a good solution for the problem you have described.

The key to your solution will be the answer to "how does the process identify the tenant". Once that is solved, the tenant will drive the strategy used.

DwB
  • 37,124
  • 11
  • 56
  • 82
1

If I understand the problem correctly, of the two, Chain of Responsibility sounds most appropriate.

I imagine an API like this:

public interface IPopulator
{
    void Populate(Foo foo);
}

You could then have an implementation for each tenant, e.g.

public class Tenant1Populator : IPopulator
{
    private readonly IPopulator next;

    public Tenant1Populator(IPopulator next)
    {
        this.next = next;
    }

    public void Populate(Foo foo)
    {
        if (!IsTenant1(foo))
        {
            next.Populate(foo);
            return;
        }

        // Else, populate foo here...
    }
}

Other implementations would follow a similar template.

There's more than one way to skin this cat, though. Another option is to let each 'handler' internally detect whether it wants to do something to the object or not, and then use the Composite pattern to ask all composed objects to do their thing.

FWIW, the drawing in the OP looks appropriate to me. The Decorator pattern would enable you to let each class do part of the job. If this is more desirable, then that could work, too.

It really depends on which part of the code you expect to have to change the most.

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736