Skip to main content
added 55 characters in body
Source Link
Flater
  • 59.6k
  • 8
  • 112
  • 171

Composition over inheritance

[A] Composition over inheritance is generally a good rule to follow,
[B] but there are some cases where inheritance is a must

Your conclusion in B implies that you are understanding A to mean "composition should always be used instead of inheritance". This interpretation is not correct.

There are some cases where inheritance is the only reasonable working solution. There are some cases where composition is the only reasonable working solution. Neither of these cases are relevant when considering "composition over inheritance".

There are some cases where composition and inheritance are both reasonable working solutions. "Composition over inheritance" advises that in these specific cases where either would a viable solution, that you should favor composition because it's not as likely for you to end up having painted yourself in a corner later on in the development cycle.

The example you bring to the table is one where inheritance is the only reasonable workable solution, and is therefore irrelevant as to the "composition over inheritance" guideline.
Similarly, the hypothetical you present is one where composition is the only reasonable workable solution, and is therefore equally irrelevant as to the "composition over inheritance" guideline.

The core of the question is irrespective of composition over inheritance. You're essentially asking "how to do A, which only works in situation X, while at the same time doing B, which only works in situation !X". By definition, you can't.

The question is: are there any existing strategies to achieve this behavior via composition that do not involve things like external maps or pointer hackery?

You already pre-empted the response, but in cases where only inheritance makes sense and not composition, just use inheritance.

Using the wrong solution for your scenario means that any difficulties you encounter from doing so are a self-imposed hurdle, and trying to make it work without addressing that hurdle turns into an XY problem really quickly.

Of course the obvious answer is "just use inheritance", but if the Node class is made by a factory or is otherwise inconvenient to inherit from, what are the alternatives? Obviously a map is one option, but that is very inconvenient and messy, and not to mention slow.

If the Node class is maintained by you, then this is another self-imposed hurdle. The obvious solution is to adapt the Node implementation so that it is inheritance-friendly.

If the Node class is maintained by the library developer, the same advice applies as it does for any complaint about the library you're using: either find another library to use, get the library developer to change their library, or deal with it. That last option then also entails letting go of the fact that it's going to require a dirty hack to get it working the way you need it to.

If the library designer chose to make it impossible to derive the Node class, or unknowingly designed their library in a way that makes it impossible, then that's how the library is designed. Any circumvention of that design is therefore by definition a hack.

An informal way to define a hack is that it is an inferior/shoddy solution when a better solution is available. The corollary here is that if there are no better solutions to the problem, then it's not a hack.

Composition over inheritance

[A] Composition over inheritance is generally a good rule to follow,
[B] but there are some cases where inheritance is a must

Your conclusion in B implies that you are understanding A to mean "composition should always be used instead of inheritance". This interpretation is not correct.

There are some cases where inheritance is the only working solution. There are some cases where composition is the only working solution. Neither of these cases are relevant when considering "composition over inheritance".

There are some cases where composition and inheritance are both working solutions. "Composition over inheritance" advises that in these specific cases where either would a viable solution, that you should favor composition because it's not as likely for you to end up having painted yourself in a corner later on in the development cycle.

The example you bring to the table is one where inheritance is the only workable solution, and is therefore irrelevant as to the "composition over inheritance" guideline.
Similarly, the hypothetical you present is one where composition is the only workable solution, and is therefore equally irrelevant as to the "composition over inheritance" guideline.

The core of the question is irrespective of composition over inheritance. You're essentially asking "how to do A, which only works in situation X, while at the same time doing B, which only works in situation !X". By definition, you can't.

The question is: are there any existing strategies to achieve this behavior via composition that do not involve things like external maps or pointer hackery?

You already pre-empted the response, but in cases where only inheritance makes sense and not composition, just use inheritance.

Using the wrong solution for your scenario means that any difficulties you encounter from doing so are a self-imposed hurdle, and trying to make it work without addressing that hurdle turns into an XY problem really quickly.

Of course the obvious answer is "just use inheritance", but if the Node class is made by a factory or is otherwise inconvenient to inherit from, what are the alternatives? Obviously a map is one option, but that is very inconvenient and messy, and not to mention slow.

If the Node class is maintained by you, then this is another self-imposed hurdle. The obvious solution is to adapt the Node implementation so that it is inheritance-friendly.

If the Node class is maintained by the library developer, the same advice applies as it does for any complaint about the library you're using: either find another library to use, get the library developer to change their library, or deal with it. That last option then also entails letting go of the fact that it's going to require a dirty hack to get it working the way you need it to.

If the library designer chose to make it impossible to derive the Node class, or unknowingly designed their library in a way that makes it impossible, then that's how the library is designed. Any circumvention of that design is therefore by definition a hack.

An informal way to define a hack is that it is an inferior/shoddy solution when a better solution is available. The corollary here is that if there are no better solutions to the problem, then it's not a hack.

Composition over inheritance

[A] Composition over inheritance is generally a good rule to follow,
[B] but there are some cases where inheritance is a must

Your conclusion in B implies that you are understanding A to mean "composition should always be used instead of inheritance". This interpretation is not correct.

There are some cases where inheritance is the only reasonable working solution. There are some cases where composition is the only reasonable working solution. Neither of these cases are relevant when considering "composition over inheritance".

There are some cases where composition and inheritance are both reasonable working solutions. "Composition over inheritance" advises that in these specific cases where either would a viable solution, that you should favor composition because it's not as likely for you to end up having painted yourself in a corner later on in the development cycle.

The example you bring to the table is one where inheritance is the only reasonable workable solution, and is therefore irrelevant as to the "composition over inheritance" guideline.
Similarly, the hypothetical you present is one where composition is the only reasonable workable solution, and is therefore equally irrelevant as to the "composition over inheritance" guideline.

The core of the question is irrespective of composition over inheritance. You're essentially asking "how to do A, which only works in situation X, while at the same time doing B, which only works in situation !X". By definition, you can't.

The question is: are there any existing strategies to achieve this behavior via composition that do not involve things like external maps or pointer hackery?

You already pre-empted the response, but in cases where only inheritance makes sense and not composition, just use inheritance.

Using the wrong solution for your scenario means that any difficulties you encounter from doing so are a self-imposed hurdle, and trying to make it work without addressing that hurdle turns into an XY problem really quickly.

Of course the obvious answer is "just use inheritance", but if the Node class is made by a factory or is otherwise inconvenient to inherit from, what are the alternatives? Obviously a map is one option, but that is very inconvenient and messy, and not to mention slow.

If the Node class is maintained by you, then this is another self-imposed hurdle. The obvious solution is to adapt the Node implementation so that it is inheritance-friendly.

If the Node class is maintained by the library developer, the same advice applies as it does for any complaint about the library you're using: either find another library to use, get the library developer to change their library, or deal with it. That last option then also entails letting go of the fact that it's going to require a dirty hack to get it working the way you need it to.

If the library designer chose to make it impossible to derive the Node class, or unknowingly designed their library in a way that makes it impossible, then that's how the library is designed. Any circumvention of that design is therefore by definition a hack.

An informal way to define a hack is that it is an inferior/shoddy solution when a better solution is available. The corollary here is that if there are no better solutions to the problem, then it's not a hack.

added 16 characters in body
Source Link
Flater
  • 59.6k
  • 8
  • 112
  • 171

Composition over inheritance

[A] Composition over inheritance is generally a good rule to follow,
[B] but there are some cases where inheritance is a must

Your conclusion in B implies that you are understanding A to mean "composition should always be used instead of inheritance". This interpretation is not correct.

There are some cases where inheritance is the only working solution. There are some cases where composition is the only working solution. Neither of these cases are relevant when considering "composition over inheritance".

There are some cases where composition and inheritance are both working solutions. "Composition over inheritance" advises that in these specific cases where either would a viable solution, that you should favor composition because it's not as likely for you to end up having painted yourself in a corner later on in the development cycle.

The example you bring to the table is one where inheritance is the only workable solution, and is therefore irrelevant as to the "composition over inheritance" guideline.
Similarly, the hypothetical you present is one where composition is the only workable solution, and is therefore equally irrelevant as to the "composition over inheritance" guideline.

Let's use a different example. In order to positively impact climate change,The core of the advicequestion is to favor bikingirrespective of composition over driving a car where possibleinheritance. "where possible" means that this advice only applies to cases where you're both able to use your bike or your car (and thus should choose your bike); not cases where you clearly haveYou're essentially asking "how to use one and cannot usedo A, which only works in situation X, while at the othersame time doing B, which only works in situation (where your choice is inherently already forced)!X". By definition, you can't.

The question is: are there any existing strategies to achieve this behavior via composition that do not involve things like external maps or pointer hackery?

You already pre-empted the response, but in cases where only inheritance makes sense and not composition, just use inheritance.

Using the wrong solution for your scenario means that any difficulties you encounter from doing so are a self-imposed hurdle, and trying to make it work without addressing that hurdle turns into an XY problem really quickly.

Of course the obvious answer is "just use inheritance", but if the Node class is made by a factory or is otherwise inconvenient to inherit from, what are the alternatives? Obviously a map is one option, but that is very inconvenient and messy, and not to mention slow.

If the Node class is maintained by you, then this is another self-imposed hurdle. The obvious solution is to adapt the Node implementation so that it is inheritance-friendly.

If the Node class is maintained by the library developer, the same advice applies as it does for any complaint about the library you're using: either find another library to use, get the library developer to change their library, or deal with it. That last option then also entails letting go of the fact that it's going to require a dirty hack to get it working the way you need it to.

If the library designer chose to make it impossible to derive the Node class, or unknowingly designed their library in a way that makes it impossible, then that's how the library is designed. Any circumvention of that design is therefore by definition a hack.

An informal way to define a hack is that it is an inferior/shoddy solution when a better solution is available. The corollary here is that if there are no better solutions to the problem, then it's not a hack.

Composition over inheritance

[A] Composition over inheritance is generally a good rule to follow,
[B] but there are some cases where inheritance is a must

Your conclusion in B implies that you are understanding A to mean "composition should always be used instead of inheritance". This interpretation is not correct.

There are some cases where inheritance is the only working solution. There are some cases where composition is the only working solution. Neither of these cases are relevant when considering "composition over inheritance".

There are some cases where composition and inheritance are both working solutions. "Composition over inheritance" advises that in these specific cases where either would a viable solution, that you should favor composition because it's not as likely for you to end up having painted yourself in a corner later on in the development cycle.

The example you bring to the table is one where inheritance is the only workable solution, and is therefore irrelevant as to the "composition over inheritance" guideline.

Let's use a different example. In order to positively impact climate change, the advice is to favor biking over driving a car where possible. "where possible" means that this advice only applies to cases where you're both able to use your bike or your car (and thus should choose your bike); not cases where you clearly have to use one and cannot use the other (where your choice is inherently already forced).

The question is: are there any existing strategies to achieve this behavior via composition that do not involve things like external maps or pointer hackery?

You already pre-empted the response, but in cases where only inheritance makes sense and not composition, just use inheritance.

Using the wrong solution for your scenario means that any difficulties you encounter from doing so are a self-imposed hurdle, and trying to make it work without addressing that hurdle turns into an XY problem really quickly.

Of course the obvious answer is "just use inheritance", but if the Node class is made by a factory or is otherwise inconvenient to inherit from, what are the alternatives? Obviously a map is one option, but that is very inconvenient and messy, and not to mention slow.

If the Node class is maintained by you, then this is another self-imposed hurdle. The obvious solution is to adapt the Node implementation so that it is inheritance-friendly.

If the Node class is maintained by the library developer, the same advice applies as it does for any complaint about the library you're using: either find another library to use, get the library developer to change their library, or deal with it. That last option then also entails letting go of the fact that it's going to require a dirty hack to get it working the way you need it to.

If the library designer chose to make it impossible to derive the Node class, or unknowingly designed their library in a way that makes it impossible, then that's how the library is designed. Any circumvention of that design is therefore by definition a hack.

Composition over inheritance

[A] Composition over inheritance is generally a good rule to follow,
[B] but there are some cases where inheritance is a must

Your conclusion in B implies that you are understanding A to mean "composition should always be used instead of inheritance". This interpretation is not correct.

There are some cases where inheritance is the only working solution. There are some cases where composition is the only working solution. Neither of these cases are relevant when considering "composition over inheritance".

There are some cases where composition and inheritance are both working solutions. "Composition over inheritance" advises that in these specific cases where either would a viable solution, that you should favor composition because it's not as likely for you to end up having painted yourself in a corner later on in the development cycle.

The example you bring to the table is one where inheritance is the only workable solution, and is therefore irrelevant as to the "composition over inheritance" guideline.
Similarly, the hypothetical you present is one where composition is the only workable solution, and is therefore equally irrelevant as to the "composition over inheritance" guideline.

The core of the question is irrespective of composition over inheritance. You're essentially asking "how to do A, which only works in situation X, while at the same time doing B, which only works in situation !X". By definition, you can't.

The question is: are there any existing strategies to achieve this behavior via composition that do not involve things like external maps or pointer hackery?

You already pre-empted the response, but in cases where only inheritance makes sense and not composition, just use inheritance.

Using the wrong solution for your scenario means that any difficulties you encounter from doing so are a self-imposed hurdle, and trying to make it work without addressing that hurdle turns into an XY problem really quickly.

Of course the obvious answer is "just use inheritance", but if the Node class is made by a factory or is otherwise inconvenient to inherit from, what are the alternatives? Obviously a map is one option, but that is very inconvenient and messy, and not to mention slow.

If the Node class is maintained by you, then this is another self-imposed hurdle. The obvious solution is to adapt the Node implementation so that it is inheritance-friendly.

If the Node class is maintained by the library developer, the same advice applies as it does for any complaint about the library you're using: either find another library to use, get the library developer to change their library, or deal with it. That last option then also entails letting go of the fact that it's going to require a dirty hack to get it working the way you need it to.

If the library designer chose to make it impossible to derive the Node class, or unknowingly designed their library in a way that makes it impossible, then that's how the library is designed. Any circumvention of that design is therefore by definition a hack.

An informal way to define a hack is that it is an inferior/shoddy solution when a better solution is available. The corollary here is that if there are no better solutions to the problem, then it's not a hack.

added 1521 characters in body
Source Link
Flater
  • 59.6k
  • 8
  • 112
  • 171

Composition over inheritance

[A] Composition over inheritance is generally a good rule to follow,
[B] but there are some cases where inheritance is a must

Your conclusion in B implies that you are understanding A to mean "composition should always be used instead of inheritance". This interpretation is not correct.

There are some cases where inheritance is the only working solution. There are some cases where composition is the only working solution. Neither of these cases are relevant when considering "composition over inheritance".

There are some cases where composition and inheritance are both working solutions. "Composition over inheritance" advises that in these specific cases where either would a viable solution, that you should favor composition because it's not as likely for you to end up having painted yourself in a corner later on in the development cycle.

The example you bring to the table is one where inheritance is the only workable solution, and is therefore irrelevant as to the "composition over inheritance" guideline.

Let's use a different example. In order to positively impact climate change, the advice is to favor biking over driving a car where possible. "where possible" means that this advice only applies to cases where you're both able to use your bike or your car (and thus should choose your bike); not cases where you clearly have to use one and cannot use the other (where your choice is inherently already forced).

The question is: are there any existing strategies to achieve this behavior via composition that do not involve things like external maps or pointer hackery?

You already pre-empted the response, but in cases where only inheritance makes sense and not composition, just use inheritance.

Using the wrong solution for your scenario means that any difficulties you encounter from doing so are a self-imposed hurdle, and trying to make it work without addressing that hurdle turns into an XY problem really quickly.

Of course the obvious answer is "just use inheritance", but if the Node class is made by a factory or is otherwise inconvenient to inherit from, what are the alternatives? Obviously a map is one option, but that is very inconvenient and messy, and not to mention slow.

If the Node class is maintained by you, then this is another self-imposed hurdle. The obvious solution is to adapt the Node implementation so that it is inheritance-friendly.

If the Node class is maintained by the library developer, the same advice applies as it does for any complaint about the library you're using: either deal with it, find another library to use, or get the library developer to change their library, or deal with it.
If That last option then also entails letting go of the fact that it's going to require a dirty hack to get it working the way you need it to.

If the library designer chose to make it impossible to derive the Node class, or unknowingly designed their library in a way that makes it impossible, then that's how the library is designed. Any circumvention of that design is therefore by definition a hack.

Composition over inheritance

[A] Composition over inheritance is generally a good rule to follow,
[B] but there are some cases where inheritance is a must

Your conclusion in B implies that you are understanding A to mean "composition should always be used instead of inheritance". This interpretation is not correct.

There are some cases where inheritance is the only working solution. There are some cases where composition is the only working solution. Neither of these cases are relevant when considering "composition over inheritance".

There are some cases where composition and inheritance are both working solutions. "Composition over inheritance" advises that in these specific cases where either would a viable solution, that you should favor composition because it's not as likely for you to end up having painted yourself in a corner later on in the development cycle.

The example you bring to the table is one where inheritance is the only workable solution, and is therefore irrelevant as to the "composition over inheritance" guideline.

Let's use a different example. In order to positively impact climate change, the advice is to favor biking over driving a car where possible. "where possible" means that this advice only applies to cases where you're both able to use your bike or your car (and thus should choose your bike); not cases where you clearly have to use one and cannot use the other (where your choice is inherently already forced).

The question is: are there any existing strategies to achieve this behavior via composition that do not involve things like external maps or pointer hackery?

You already pre-empted the response, but in cases where only inheritance makes sense and not composition, just use inheritance.

Using the wrong solution for your scenario means that any difficulties you encounter from doing so are a self-imposed hurdle, and trying to make it work without addressing that hurdle turns into an XY problem really quickly.

Of course the obvious answer is "just use inheritance", but if the Node class is made by a factory or is otherwise inconvenient to inherit from, what are the alternatives? Obviously a map is one option, but that is very inconvenient and messy, and not to mention slow.

If the Node class is maintained by you, then this is another self-imposed hurdle. The obvious solution is to adapt the Node implementation so that it is inheritance-friendly.

If the Node class is maintained by the library developer, the same advice applies as it does for any complaint about the library you're using: either deal with it, find another library to use, or get the library developer to change their library.
If the library designer chose to make it impossible to derive the Node class, then that's how the library is designed. Any circumvention of that design is therefore by definition a hack.

Composition over inheritance

[A] Composition over inheritance is generally a good rule to follow,
[B] but there are some cases where inheritance is a must

Your conclusion in B implies that you are understanding A to mean "composition should always be used instead of inheritance". This interpretation is not correct.

There are some cases where inheritance is the only working solution. There are some cases where composition is the only working solution. Neither of these cases are relevant when considering "composition over inheritance".

There are some cases where composition and inheritance are both working solutions. "Composition over inheritance" advises that in these specific cases where either would a viable solution, that you should favor composition because it's not as likely for you to end up having painted yourself in a corner later on in the development cycle.

The example you bring to the table is one where inheritance is the only workable solution, and is therefore irrelevant as to the "composition over inheritance" guideline.

Let's use a different example. In order to positively impact climate change, the advice is to favor biking over driving a car where possible. "where possible" means that this advice only applies to cases where you're both able to use your bike or your car (and thus should choose your bike); not cases where you clearly have to use one and cannot use the other (where your choice is inherently already forced).

The question is: are there any existing strategies to achieve this behavior via composition that do not involve things like external maps or pointer hackery?

You already pre-empted the response, but in cases where only inheritance makes sense and not composition, just use inheritance.

Using the wrong solution for your scenario means that any difficulties you encounter from doing so are a self-imposed hurdle, and trying to make it work without addressing that hurdle turns into an XY problem really quickly.

Of course the obvious answer is "just use inheritance", but if the Node class is made by a factory or is otherwise inconvenient to inherit from, what are the alternatives? Obviously a map is one option, but that is very inconvenient and messy, and not to mention slow.

If the Node class is maintained by you, then this is another self-imposed hurdle. The obvious solution is to adapt the Node implementation so that it is inheritance-friendly.

If the Node class is maintained by the library developer, the same advice applies as it does for any complaint about the library you're using: either find another library to use, get the library developer to change their library, or deal with it. That last option then also entails letting go of the fact that it's going to require a dirty hack to get it working the way you need it to.

If the library designer chose to make it impossible to derive the Node class, or unknowingly designed their library in a way that makes it impossible, then that's how the library is designed. Any circumvention of that design is therefore by definition a hack.

added 1521 characters in body
Source Link
Flater
  • 59.6k
  • 8
  • 112
  • 171
Loading
added 1521 characters in body
Source Link
Flater
  • 59.6k
  • 8
  • 112
  • 171
Loading
Source Link
Flater
  • 59.6k
  • 8
  • 112
  • 171
Loading