Skip to main content
Commonmark migration
Source Link

Decorator pattern

Let's start off nice: I hate your second solution.

IVideoPlayer is an interface; a "contract" that any implementing class does a certain thing. It's a contract on the code side (between caller and implementation), but in a way it's also interpersonal between the programmers working with it - the compiler won't stop me if I implement IVideoPlayer with Play() erasing the hard drive.

The 2 implementations are not fulfilling the same contract, they just have a method with the same name.

The safety an interface is supposed to provide is not given here. Even worse, because of this expectation of such a contract, it makes it more likely that somebody will get it wrong.

Naming things

There are 2 hard thing in computer science, one of them is naming things. Don't underestimate it, a thesaurus is one of the most undervalued programming tools. You should have 2 different names that convey the difference between the 2 implementations.

To give examples, you could rename the "outer" one to VideoSystem: one is the whole system, while the other one is only the player. Or you could rename the inner one VideoRenderer: one is the whole player, while the other is only the part "rendering" the video.

As the outer one seems to be an exposed API, I would rather go with renaming the inner one, because you can easier explain the inner one to your coworkers than the outer one to your clients.

Patterns

Wikipedia says about the Decorator Pattern

What problems can the Decorator design pattern solve?

  • Responsibilities should be added to (and removed from) an object dynamically at run-time.
  • A flexible alternative to subclassing for extending functionality should be provided.

About the Facade Pattern, Wikipedia says

What problems can the Facade design pattern solve?

 
  • To make a complex subsystem easier to use, a simple interface should be provided for a set of interfaces in the subsystem.
  • The dependencies on a subsystem should be minimized.

Neither of those is your goal here.

You're not working on this because you want to add or remove things dynamically at run-time, or want to extend functionality, or because your subsystem is too difficult to use, or you have too many dependencies on a subsystem.

You are trying to create some functionality in the first place.

Solution

Don't think "which pattern should I apply". Do what works. In the end your code might turn out to be an already established pattern and then when your coworkers ask about the code you can tell them "I solved it with {pattern name}". That's about all the advantage you get from using a pattern.

All that being said, do the first thing.

However, calling that a facade might be confusing, because a lot of people see facades as rather simple classes, just "passing along" methods (e.g. if you also had a method Connect() calling _internetConnection.Connect();). Examples on Wikipedia say otherwise, but they don't seem to be particularly good (e.g. repeatedly calling new in constructors).

You have a VideoPlayer class, and to do its job, it needs other classes - I'd just call that good old composition. Nobody will misunderstand you if you call it composition.

Decorator pattern

Let's start off nice: I hate your second solution.

IVideoPlayer is an interface; a "contract" that any implementing class does a certain thing. It's a contract on the code side (between caller and implementation), but in a way it's also interpersonal between the programmers working with it - the compiler won't stop me if I implement IVideoPlayer with Play() erasing the hard drive.

The 2 implementations are not fulfilling the same contract, they just have a method with the same name.

The safety an interface is supposed to provide is not given here. Even worse, because of this expectation of such a contract, it makes it more likely that somebody will get it wrong.

Naming things

There are 2 hard thing in computer science, one of them is naming things. Don't underestimate it, a thesaurus is one of the most undervalued programming tools. You should have 2 different names that convey the difference between the 2 implementations.

To give examples, you could rename the "outer" one to VideoSystem: one is the whole system, while the other one is only the player. Or you could rename the inner one VideoRenderer: one is the whole player, while the other is only the part "rendering" the video.

As the outer one seems to be an exposed API, I would rather go with renaming the inner one, because you can easier explain the inner one to your coworkers than the outer one to your clients.

Patterns

Wikipedia says about the Decorator Pattern

What problems can the Decorator design pattern solve?

  • Responsibilities should be added to (and removed from) an object dynamically at run-time.
  • A flexible alternative to subclassing for extending functionality should be provided.

About the Facade Pattern, Wikipedia says

What problems can the Facade design pattern solve?

 
  • To make a complex subsystem easier to use, a simple interface should be provided for a set of interfaces in the subsystem.
  • The dependencies on a subsystem should be minimized.

Neither of those is your goal here.

You're not working on this because you want to add or remove things dynamically at run-time, or want to extend functionality, or because your subsystem is too difficult to use, or you have too many dependencies on a subsystem.

You are trying to create some functionality in the first place.

Solution

Don't think "which pattern should I apply". Do what works. In the end your code might turn out to be an already established pattern and then when your coworkers ask about the code you can tell them "I solved it with {pattern name}". That's about all the advantage you get from using a pattern.

All that being said, do the first thing.

However, calling that a facade might be confusing, because a lot of people see facades as rather simple classes, just "passing along" methods (e.g. if you also had a method Connect() calling _internetConnection.Connect();). Examples on Wikipedia say otherwise, but they don't seem to be particularly good (e.g. repeatedly calling new in constructors).

You have a VideoPlayer class, and to do its job, it needs other classes - I'd just call that good old composition. Nobody will misunderstand you if you call it composition.

Decorator pattern

Let's start off nice: I hate your second solution.

IVideoPlayer is an interface; a "contract" that any implementing class does a certain thing. It's a contract on the code side (between caller and implementation), but in a way it's also interpersonal between the programmers working with it - the compiler won't stop me if I implement IVideoPlayer with Play() erasing the hard drive.

The 2 implementations are not fulfilling the same contract, they just have a method with the same name.

The safety an interface is supposed to provide is not given here. Even worse, because of this expectation of such a contract, it makes it more likely that somebody will get it wrong.

Naming things

There are 2 hard thing in computer science, one of them is naming things. Don't underestimate it, a thesaurus is one of the most undervalued programming tools. You should have 2 different names that convey the difference between the 2 implementations.

To give examples, you could rename the "outer" one to VideoSystem: one is the whole system, while the other one is only the player. Or you could rename the inner one VideoRenderer: one is the whole player, while the other is only the part "rendering" the video.

As the outer one seems to be an exposed API, I would rather go with renaming the inner one, because you can easier explain the inner one to your coworkers than the outer one to your clients.

Patterns

Wikipedia says about the Decorator Pattern

What problems can the Decorator design pattern solve?

  • Responsibilities should be added to (and removed from) an object dynamically at run-time.
  • A flexible alternative to subclassing for extending functionality should be provided.

About the Facade Pattern, Wikipedia says

What problems can the Facade design pattern solve?

  • To make a complex subsystem easier to use, a simple interface should be provided for a set of interfaces in the subsystem.
  • The dependencies on a subsystem should be minimized.

Neither of those is your goal here.

You're not working on this because you want to add or remove things dynamically at run-time, or want to extend functionality, or because your subsystem is too difficult to use, or you have too many dependencies on a subsystem.

You are trying to create some functionality in the first place.

Solution

Don't think "which pattern should I apply". Do what works. In the end your code might turn out to be an already established pattern and then when your coworkers ask about the code you can tell them "I solved it with {pattern name}". That's about all the advantage you get from using a pattern.

All that being said, do the first thing.

However, calling that a facade might be confusing, because a lot of people see facades as rather simple classes, just "passing along" methods (e.g. if you also had a method Connect() calling _internetConnection.Connect();). Examples on Wikipedia say otherwise, but they don't seem to be particularly good (e.g. repeatedly calling new in constructors).

You have a VideoPlayer class, and to do its job, it needs other classes - I'd just call that good old composition. Nobody will misunderstand you if you call it composition.

Source Link
R. Schmitz
  • 2.6k
  • 1
  • 17
  • 28

Decorator pattern

Let's start off nice: I hate your second solution.

IVideoPlayer is an interface; a "contract" that any implementing class does a certain thing. It's a contract on the code side (between caller and implementation), but in a way it's also interpersonal between the programmers working with it - the compiler won't stop me if I implement IVideoPlayer with Play() erasing the hard drive.

The 2 implementations are not fulfilling the same contract, they just have a method with the same name.

The safety an interface is supposed to provide is not given here. Even worse, because of this expectation of such a contract, it makes it more likely that somebody will get it wrong.

Naming things

There are 2 hard thing in computer science, one of them is naming things. Don't underestimate it, a thesaurus is one of the most undervalued programming tools. You should have 2 different names that convey the difference between the 2 implementations.

To give examples, you could rename the "outer" one to VideoSystem: one is the whole system, while the other one is only the player. Or you could rename the inner one VideoRenderer: one is the whole player, while the other is only the part "rendering" the video.

As the outer one seems to be an exposed API, I would rather go with renaming the inner one, because you can easier explain the inner one to your coworkers than the outer one to your clients.

Patterns

Wikipedia says about the Decorator Pattern

What problems can the Decorator design pattern solve?

  • Responsibilities should be added to (and removed from) an object dynamically at run-time.
  • A flexible alternative to subclassing for extending functionality should be provided.

About the Facade Pattern, Wikipedia says

What problems can the Facade design pattern solve?

  • To make a complex subsystem easier to use, a simple interface should be provided for a set of interfaces in the subsystem.
  • The dependencies on a subsystem should be minimized.

Neither of those is your goal here.

You're not working on this because you want to add or remove things dynamically at run-time, or want to extend functionality, or because your subsystem is too difficult to use, or you have too many dependencies on a subsystem.

You are trying to create some functionality in the first place.

Solution

Don't think "which pattern should I apply". Do what works. In the end your code might turn out to be an already established pattern and then when your coworkers ask about the code you can tell them "I solved it with {pattern name}". That's about all the advantage you get from using a pattern.

All that being said, do the first thing.

However, calling that a facade might be confusing, because a lot of people see facades as rather simple classes, just "passing along" methods (e.g. if you also had a method Connect() calling _internetConnection.Connect();). Examples on Wikipedia say otherwise, but they don't seem to be particularly good (e.g. repeatedly calling new in constructors).

You have a VideoPlayer class, and to do its job, it needs other classes - I'd just call that good old composition. Nobody will misunderstand you if you call it composition.