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?

asked Oct 25, 2018 at 7:26

3 Answers 3

6

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.

answered Oct 25, 2018 at 7:55
2

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.

answered Oct 26, 2018 at 12:36
6
  • What if the special methods are private methods that only make sense in the implementation class? I think that's OK. Commented Oct 27, 2018 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. Commented Oct 27, 2018 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. Commented Oct 27, 2018 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. Commented Oct 27, 2018 at 11:56
  • That is very insightful. Thanks for the explanation. Commented Oct 28, 2018 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.

answered Oct 25, 2018 at 8:05
1
  • I think OP means the body of each applyFilter will involve calls to shared code Commented Oct 25, 2018 at 8:12

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.