1

First of all I am going to give you a brief explanation of what i am after doing. I want to write a program that applies filters to an image using a strategy design pattern. I have read some documentations about the pattern and decided to use it like this.

First I will create an Interface called FilterStrategy which has one method called applyFilter.

After that I create 2 different classes, lets call them BeautifulFilter and UglyFilter that implement the interface above.

Then I will write a context class which has a private member of FilterStrategy and a setter method for two different strategies. And lastly one more method in which i call the applyFilter

In main my function I create a FilterStrategy and set the filter for UglyFilter and call the function.

Here is what I am asking. BeautifulFilter and UglyFilter has many common methods such as read image, write image, convolution and display... and there also some methods that are used by only one of the filters above. Where am I supposed to implement these methods? Should I duplicate my code in both of the filter classes?

5

I would implement a parent class for your filters eg FilterBase

This FilterBase would implement the read, write, convolution and display methods. Then when your classes BeautifulFilter and UglyFilter inherit from it, they would be able to access the methods themselves.

1

Here is what I am asking. BeautifulFilter and UglyFilter has many common methods such as read image, write image, convolution and display...

So far this sounds fine.

and there also some methods that are used by only one of the filters above.

And here's where it goes to hell.

Where am I supposed to implement these methods? Should I duplicate my code in both of the filter classes?

Look you can't have special methods that can only be called if it's the right type and use the strategy pattern. Or template method pattern or even naked inheritance. Polymorphism just doesn't work that way. You can't ask the using code to know what the type is.

My favorite example for this telling pets to speak. I like not having to tell a dog to bark or a duck to quack. I can just say pet.speak() and whatever pet that is figures out what to do. If I sometimes need silence I don't wrap the speak command in an if, I use a cat (otherwise known as the null object pattern). You tell it to speak and it ignores you (cause it's a cat). My cat can be carefully designed to quietly accept and ignore every possible message (or ignore just some of them). I can send my cat to anything that works with pets and things still work nicely without blowing up. However, my pet rock is another issue. You tell my pet rock to speak and it tears a hole in the fabric of reality by complaining that it doesn't know how to speak because I never taught it how. Now sure you can be careful and check for rocks before asking it to speak but it's easier to use cats. They're really good at doing nothing.

  • What if the special methods are private methods that only make sense in the implementation class? I think that's OK. – du369 Oct 27 '18 at 9:17
  • 1
    @du369 of course it is. Polymorphism is about the using code. What happens hidden inside is nobody else's business.Encapsulation is a good thing. – candied_orange Oct 27 '18 at 9:22
  • So if I am understanding you correctly, your answer is about "not to pollute an interface with special methods that only make sense to some (not all) implementation". For that, I totally agree. – du369 Oct 27 '18 at 9:24
  • 1
    @du369 that's the principle to follow. But I'm also showing how to accommodate differences that tempt you to break it. Prefer abstract messages like speak() to bark(). Use them even if it's a cat that won't meow on command. Accept the message. Just don't meow. Design the class around how it will be used. Not around what you think it is. – candied_orange Oct 27 '18 at 11:56
  • That is very insightful. Thanks for the explanation. – du369 Oct 28 '18 at 1:54
0

From what you describe context class should be concerned with loading/writing image and filter should be concerned only with changing image data. I believe image manipulation code will be complex enough.

So filter classes would have one method ApplyFilter() that takes image data as parameter and returns image data with filtering applied.

  • I think OP means the body of each applyFilter will involve calls to shared code – Caleth Oct 25 '18 at 8:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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