The Java way surely is maximizing the extensibility. I think it uses the decorator pattern, so it ends up looking like an onion. I also think it's more object-oriented, but also more complex. I'm guilty of making interfaces like this, and I realize it can get hard to understand if you come back to it a few months later. I still think it's worth because of the flexibility you have, but of course, it depends on your use-case. If you will only have one type of streams, a design like this would certainly be over-engineering.
The builder and factory patterns are quite similar in this context, and I think any of those could be used. I like factories to create several instances of related classes, and builders to arrange several more generic objects together.
As for my example, I think I made a mistake there, it should have been something like stream = MyBuilder.build(some: :parameter), thanks for pointing that out :) I was thinking about doing a DSL example but that might be too Ruby-ish and it would miss the point.
I like something the author mentions. He says something like "The default use-case should be easy for the consumer". In the Java example, while it's super flexible, if the user will want a buffered stream most of the time, why not just make that the default, and allow other decorators to be applied if needed?
So maybe the answer is that we need to understand what we are designing for.
Yes! And because it's impossible to know upfront what we are designing for, the design needs to change and adapt as the software grows.
You surely need something before designing, but that thing will surely change as your software grows, and then you'll need to adapt the design. That's why the waterfall model is dead, unless you really know what you are doing (eg: you are writing v3 of something).
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
The Java way surely is maximizing the extensibility. I think it uses the decorator pattern, so it ends up looking like an onion. I also think it's more object-oriented, but also more complex. I'm guilty of making interfaces like this, and I realize it can get hard to understand if you come back to it a few months later. I still think it's worth because of the flexibility you have, but of course, it depends on your use-case. If you will only have one type of streams, a design like this would certainly be over-engineering.
The builder and factory patterns are quite similar in this context, and I think any of those could be used. I like factories to create several instances of related classes, and builders to arrange several more generic objects together.
As for my example, I think I made a mistake there, it should have been something like
stream = MyBuilder.build(some: :parameter)
, thanks for pointing that out :) I was thinking about doing a DSL example but that might be too Ruby-ish and it would miss the point.I like something the author mentions. He says something like "The default use-case should be easy for the consumer". In the Java example, while it's super flexible, if the user will want a buffered stream most of the time, why not just make that the default, and allow other decorators to be applied if needed?
Yes! And because it's impossible to know upfront what we are designing for, the design needs to change and adapt as the software grows.
I think the first step to designing is to find out what you are designing for.
You surely need something before designing, but that thing will surely change as your software grows, and then you'll need to adapt the design. That's why the waterfall model is dead, unless you really know what you are doing (eg: you are writing v3 of something).