-1

I am working on an application which allows its users to apply different filters on an image that they upload. However, there is another requirement that needs to be fulfilled here. The application should allow the user to apply several filters on top of each other with a cumulative effect on the original image. Is there a design pattern that I can use to implement this? I have come up with the following two approaches which could be used to implement this design:

  1. Composite pattern: Have a Filter interface which is implemented by the various ConcreteFilter classes and define a new class CompositeFilter which collects Filter instances.
  2. Decorator pattern with no concrete components: Have a Filter abstract class that contains a reference to an object of Filter itself which is extended by the various ConcreteFilter classes (which are the decorators in this case).

The first option seems more appropriate to me as I'm not sure that the second method satisfies the intent of a Decorator pattern: adding additional responsibilities to (enhancing) a single component dynamically. What are potential uses and drawbacks for each approach and which one can be used to satisfy the requirement?

Thanks.

Fandango
  • 11
  • 1
  • I don't believe that your issue concerns design patterns (which describe general strategies for handling particular software engineering problems, e.g. the abstract factory pattern) as much as it does a particular design decision. A decorator pattern is similar to the wrapper pattern wherein a class may add instrumentation to a wrapped object by adding new functionality and delegating to the contained instance. I don't think that this is what your question speaks to. – scottb Dec 09 '14 at 05:52
  • @scottb Thanks for the comment. I forgot to mention that the `Filter` class will have a reference as well. I edited the question to add this detail. – Fandango Dec 09 '14 at 05:59
  • Could the downvoter please explain why this question isn't good enough so that I can avoid making mistakes in the future? – Fandango Dec 09 '14 at 06:15
  • You've got a broad, unspecific problem more related to application design than to programming, which is also somewhat opinion based. That's not a good fit for SO. Whiteboard-style architecture questions are better asked on the programmers SE site, given the question is of high quality and answerable by facts, not opinions. – l4mpi Dec 09 '14 at 11:33

1 Answers1

1

If your question is "should I add my feature by using an interface-based type system" versus "should I add my feature by using an abstract class", then the answer is usually ... both.

Interfaces should be used where possible to define types. Having a Filter interface that forms the contract for how your filter-classes implement their functionality is absolutely the right thing to do.

The chief advantage of abstract classes is that they enable you to provide a partial or nearly complete implementation for the type. They were once the only way to provide default methods prior to Java 8 (and now Java 8 allows you to place default methods in interface declarations).

So what I suggest is the following:

  1. Define your type with an interface.

  2. If your type has implementation that is common to all members of your type (such as shared fields or default methods), then the right thing to do is declare an abstract class that implements your type interface. By convention, the abstract class for a type interface named "Type" would be "AbstractType".

It is then a simple matter for all your filter classes to simply extend AbstractFilter. Then your type gains all the advantages of an interface-based type system as well as the advantages of an abstract class that simplifies the work of implementors. You may also wish to consider the abstract decorator pattern if it fits your needs: Question about decorator pattern and the abstract decorator class?

Community
  • 1
  • 1
scottb
  • 9,908
  • 3
  • 40
  • 56
  • Thanks for the answer. I understand that I could use an interface which is implemented by the abstract class to gain both their advantages. But, this doesn't answer my question as to whether I should be using Decorator or Composite. – Fandango Dec 09 '14 at 06:12
  • It is a software engineering decision. You can do both. I guess I don't know enough about your requirements, code base, or constraints to be able to say. Design patters are general approaches to particular, commonly encountered situations; they are not intended to be full-featured abstractions. I suppose you could use either pattern ... or both. It just depends. This question may be similar to your own: http://stackoverflow.com/questions/6186295/decorator-design-pattern-using-inheritance-vs-interfaces?rq=1 – scottb Dec 09 '14 at 11:09