-1

I am a noob in design principles and design patterns, this might seem like a very silly question.

Some classes in my code have the following structure (image linked):

https://ibb.co/nrp1t2g

As you can see, I have an interface implemented by 3 classes, and each class overrides the interface method execute(string, long, long).

Now, I need an extra function parameter for only the 3rd class, UpdateInDbOperation. I have shown my requirement in the linked diagram below (see the red marked portion in the diagram). For UpdateInDbOperation class, a fourth parameter of string type will be needed.

https://ibb.co/sCHzhwB

The problems:

  1. If I add a fourth parameter to my interface, the first two implementing classes will break.
  2. I am looking for a way to solve this issue without violating the open - closed principle.

Why I am implementing from IOperation interface:

  1. For simplicity I have NOT shown other methods of the IOperation interface. IOperation contains some another method which is implemented by all 3 classes. No change is needed in that method.
  2. In one region of my codebase, chain of responsibility design pattern is used to pass an object through all the classes implementing IOperation.
  3. For these reasons, I cannot stop using IOperation. Simply put, up till now my design was working smoothly, and I thought it to be very extensible. But because of the extra parameter in UpdateInDbOperation, I am confused over the whole design now.

What I have already tried / researched:

  1. The problem can be solved by using parameters with default values, but I want to avoid them. In the future similar situations may arise again. If I keep on increasing parameters with default values, then eventually the method callers will forget the actual number of parameters. Default value parameters will also add totally unused code to the first two classes.
  2. The problem can be solved by using C# params keyword (https://www.geeksforgeeks.org/c-sharp-params/), but this will make my interface extremely flexible. Personally I think an interface should provide a somewhat specific blueprint, but if I use C# params then virtually any class can implement the interface.
  3. I have tried to fit this issue into the Command design pattern. But most examples of Command I have seen use methods/functions without parameters.
  4. I have gone through one implementation of Command pattern in the following link (https://www.geeksforgeeks.org/command-pattern/?ref=lbp). This uses another secondary interface to isolate the method parameters. But I am not sure whether this can be used in my case.

Web links I have gone through:

  1. How to adhere to the open-closed principle in practice
  2. Open Closed principle in design patterns
  3. https://www.geeksforgeeks.org/open-closed-principle-in-java-with-examples/
2
  • 2
    Put it in the constructor, supply the value at construction time and save it as a member field, then use later internally in the 'execute' call. This is what constructors and object state are for. May 13, 2022 at 15:00
  • I cannot see the images, links don't seem to work for me, which makes you question useless. Please use the mechanics for images provided by stackexchange.
    – Doc Brown
    May 17, 2022 at 10:30

1 Answer 1

0

The solution is to eliminate the IOperation interface which you don't need.

You don't describe the semantics of the extra parameter, but presumably it is something specific for the database operation. Therefore the code calling the operation needs to know it is calling a database operation in order to provide a meaningful value. The IOperation interface seem to be unnecessary then, and there is nothing in how you describe the problem which require this interface.

2
  • I have edited my question to explain the reason behind using IOperation. I cannot stop using IOperation because then other parts of the code will break.
    – Shuaib
    May 13, 2022 at 12:54
  • 2
    @Shuaib: Then this is possibly an XY problem and the issue is with the implementation of the chain of responsibility. But I think the root of the problem is you leave out the parameter names of the method. This means the semantics of the operation does not inform the design, and design should always be guided by the semantics.
    – JacquesB
    May 13, 2022 at 13:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.