How we can use OCP with delegation?

181 Views Asked by At

There are a lot samples of using OCP with help of inheritance. But I am confused how we can use OCP with delegation. Can anyone share any sample?

2

There are 2 best solutions below

0
On BEST ANSWER

You can have a base class that delegates to a derived class as with the Template pattern. This is Open for extension by allowing derived classes, but the base class will still be closed to modification.

Here's an example in C++:

class BaseClass
{
public:
    void doStuff() {
        doStuff1(); // delegating to derived class

        // do base class stuff here

        doStuff2(); // delegating to derived class

        // do more base class stuff here

        doStuff3(); // delegating to derived class
    }

protected:
    virtual void doStuff1() = 0;
    virtual void doStuff2() = 0;
    virtual void doStuff3() = 0;
};

class DerivedClass1 : public BaseClass
{
protected:
    void doStuff1() { /* your impl here */ }
    void doStuff2() { /* your impl here */ }
    void doStuff3() { /* your impl here */ }
};

// Implement as many other derived classes as you wish

Notice you dont have to modify the BaseClass (its closed to mods) and it delegates to derived classes, and more derived classes could be implemented (open to extension)

0
On

If I get "delegation" correctly this could look like this (C#):

class Product
{
    public decimal Price {get;set;}
}

class Basket
{
    IEnumerable<Product> _products;
    Func<Product, decimal> _taxCalculator;

    public Basket(IEnumerable<Product> products, Func<Product, decimal> taxCalculator)
    {
        _products = products;
        _taxCalculator = taxCalculator;
    }

    public decimal CalculateBasketValue()
    {
        decimal sum = 0;
        foreach (var product in _products)
        {
            sum += product.Price + _taxCalculator(product);
        }
        return sum;
    }
}

public static void Main()
{
    var products = new []
    {
        new Product { Price = 100 }
    };
    var twentyPercentTax = new Func<Product, decimal>(product => product.Price * 0.2m);
    var basket = new Basket(products, twentyPercentTax);
    Console.WriteLine(basket.CalculateBasketValue());
}

The class is closed to computing the value of the basket. However it is open to the way of calculating the tax. Calculating the tax is delegated to taxCalculator. You can easily have a bunch of tax calculators and select one of them based on the country or anything else.