Skip to main content
Tweeted twitter.com/StackSoftEng/status/970561849300344832
shortened title and other small clarifications
Source Link
Jonathan
  • 211
  • 1
  • 6

How do you avoid endlessly iterating through equally sub-optimal design patterns or approachesdesigns?

So probably like many, I often find myself running into headaches with design problems in which, for example, there is some design pattern/approach that seems to intuitively fit the problem and has desired benefits. Very often there is some caveat which makes it difficult to implement the pattern/approach without some kind of work around which then negates the benefit of the pattern/approach. I can very easily end up iterating through many patterns/approaches because predictably almost all of them have some very significant caveats in real-world situations in which there simply isn't an easy solution.


Example:

I'll give you a hypothetical example based loosely on a real one I recently encountered. Let's say I want to use composition over inheritance because inheritance hierarchies have hindered the scaleability of the code in the past. I might refactor the code but then find that there are some contexts where the superclass/baseclass simply needs to call functionality on the subclass, despite attempts to avoid it.

The next best approach seems to be implementing a half delegate/observer pattern and half composition pattern so that the superclass can delegate behaviour or so that the subclass can observe superclass events. Then the class is less scaleable and maintainable because its unclear how it should be extended, also it is tricky to extend existing listeners/delegates. Also information isn't hidden well because one starts needing to know the implementation to see how to extend the superclass (unless you use comments very extensively).

So after this I might opt to simply just use observers or delegates completely to get away from the drawbacks that comes with mixing up the approaches to heavily. However this comes with its own problems. For example, I might find that I end up needing observers or delegates for an increasing amount of behaviours until I end up needing observers/delegates for practically every behaviour. One option could be to just have one big listener/delegate for all of the behaviour but then the implementing class ends up with lots of empty methods etc.

Then I might try another approach but there are just as many issues with that. Then the next one, and the one after etc.


This iterative process gets very difficult when each approach seems to have as many problems as any of the others and leads to a sort of design decision paralysis. It is also difficult to accept that the code will end up equally problematic regardless of which design pattern or approach is used. If I end up in this situation does it mean that the problem itself needs to be rethought? What do others do when they encounter this situation?

Edit: There seems to be a number of interpretations of the question that I want to clear up:

  • I have taken OOP out of the question completely because it turns out that it is not actually specific to OOP, plus it is too easy to misinterpret some of the comments I made in passing about OOP.
  • Some have claimed I should take an iterative approach and try different patterns, or that I should discard a pattern when it ceases to work. This is the process I intended to refer to in the first place. I thought this was clear from the example but I could have made it clearer, so I've edited the question to do so.

How do you avoid endlessly iterating through equally sub-optimal design patterns or approaches?

So probably like many, I often find myself running into headaches with design problems in which, for example, there is some design pattern/approach that seems to intuitively fit the problem and has desired benefits. Very often there is some caveat which makes it difficult to implement the pattern/approach without some kind of work around which then negates the benefit of the pattern/approach. I can very easily end up iterating through many patterns/approaches because predictably almost all of them have some very significant caveats in real-world situations.


Example:

I'll give you a hypothetical example based loosely on a real one I recently encountered. Let's say I want to use composition over inheritance because inheritance hierarchies have hindered the scaleability of the code in the past. I might refactor the code but then find that there are some contexts where the superclass/baseclass simply needs to call functionality on the subclass, despite attempts to avoid it.

The next best approach seems to be implementing a half delegate/observer pattern and half composition pattern so that the superclass can delegate behaviour or so that the subclass can observe superclass events. Then the class is less scaleable and maintainable because its unclear how it should be extended, also it is tricky to extend existing listeners/delegates. Also information isn't hidden well because one starts needing to know the implementation to see how to extend the superclass (unless you use comments very extensively).

So after this I might opt to simply just use observers or delegates completely to get away from the drawbacks that comes with mixing up the approaches to heavily. However this comes with its own problems. For example, I might find that I end up needing observers or delegates for an increasing amount of behaviours until I end up needing observers/delegates for practically every behaviour. One option could be to just have one big listener/delegate for all of the behaviour but then the implementing class ends up with lots of empty methods etc.

Then I might try another approach but there are just as many issues with that. Then the next one, and the one after etc.


This iterative process gets very difficult when each approach seems to have as many problems as any of the others and leads to a sort of design decision paralysis. It is also difficult to accept that the code will end up equally problematic regardless of which design pattern or approach is used. If I end up in this situation does it mean that the problem itself needs to be rethought? What do others do when they encounter this situation?

Edit: There seems to be a number of interpretations of the question that I want to clear up:

  • I have taken OOP out of the question completely because it turns out that it is not actually specific to OOP, plus it is too easy to misinterpret some of the comments I made in passing about OOP.
  • Some have claimed I should take an iterative approach and try different patterns, or that I should discard a pattern when it ceases to work. This is the process I intended to refer to in the first place. I thought this was clear from the example but I could have made it clearer, so I've edited the question to do so.

How do you avoid endlessly iterating through equally sub-optimal designs?

So probably like many, I often find myself running into headaches with design problems in which, for example, there is some design pattern/approach that seems to intuitively fit the problem and has desired benefits. Very often there is some caveat which makes it difficult to implement the pattern/approach without some kind of work around which then negates the benefit of the pattern/approach. I can very easily end up iterating through many patterns/approaches because predictably almost all of them have some very significant caveats in real-world situations in which there simply isn't an easy solution.


Example:

I'll give you a hypothetical example based loosely on a real one I recently encountered. Let's say I want to use composition over inheritance because inheritance hierarchies have hindered the scaleability of the code in the past. I might refactor the code but then find that there are some contexts where the superclass/baseclass simply needs to call functionality on the subclass, despite attempts to avoid it.

The next best approach seems to be implementing a half delegate/observer pattern and half composition pattern so that the superclass can delegate behaviour or so that the subclass can observe superclass events. Then the class is less scaleable and maintainable because its unclear how it should be extended, also it is tricky to extend existing listeners/delegates. Also information isn't hidden well because one starts needing to know the implementation to see how to extend the superclass (unless you use comments very extensively).

So after this I might opt to simply just use observers or delegates completely to get away from the drawbacks that comes with mixing up the approaches to heavily. However this comes with its own problems. For example, I might find that I end up needing observers or delegates for an increasing amount of behaviours until I end up needing observers/delegates for practically every behaviour. One option could be to just have one big listener/delegate for all of the behaviour but then the implementing class ends up with lots of empty methods etc.

Then I might try another approach but there are just as many issues with that. Then the next one, and the one after etc.


This iterative process gets very difficult when each approach seems to have as many problems as any of the others and leads to a sort of design decision paralysis. It is also difficult to accept that the code will end up equally problematic regardless of which design pattern or approach is used. If I end up in this situation does it mean that the problem itself needs to be rethought? What do others do when they encounter this situation?

Edit: There seems to be a number of interpretations of the question that I want to clear up:

  • I have taken OOP out of the question completely because it turns out that it is not actually specific to OOP, plus it is too easy to misinterpret some of the comments I made in passing about OOP.
  • Some have claimed I should take an iterative approach and try different patterns, or that I should discard a pattern when it ceases to work. This is the process I intended to refer to in the first place. I thought this was clear from the example but I could have made it clearer, so I've edited the question to do so.
Re-framed question as being distinct from the duplicate, also cleared up misinterpretations of question
Source Link
Jonathan
  • 211
  • 1
  • 6

How do you navigate OOP grey areas to avoid endlessly iterating through equally sub-optimal design decision paralysispatterns or approaches?

So probably like many, I subscribe to the OOP philosophy of programming, although I would like to think not overly-strongly. I often find myself running into headaches with OOPdesign problems in which, for example, there is some desired design pattern/approach that I would likeseems to implement because it's more OO (and therefore more maintainable, scaleable etc.)intuitively fit the problem and has desired benefits. Very often there is some caveat which makes it difficult to implement the pattern/approach without some kind of ugly and less OO workaroundwork around which then negates the benefit of the pattern/approach. I can very easily end up going around in circles betweeniterating through many patterns/approaches because predictably almost all of them have some very significant caveats in real-world situations.


Example:

I'll give you a recenthypothetical example based loosely on a real one I recently encountered. Let's say I want to use composition over inheritance because inheritance hierarchies have hindered the scaleability of the code in the past. I might refactor the code but then find that there are some contexts where the superclass/baseclass simply needs to call functionality on the subclass, despite attempts to avoid it. So then I start having

The next best approach seems to implementbe implementing a half delegate/observer pattern and half composition pattern so that the superclass can delegate behaviour or so that the subclass can observe superclass events. Then the class is less scaleable and maintainable because its unclear how it should be extended, also it is tricky to extend existing listeners/delegates. Also information isn't hidden well because one starts needing to know the implementation to see how to extend the superclass (unless you use comments very extensively).

So after this oneI might opt to simply just use observers or delegates completely to get away from the drawbacks that comes with mixing up the approaches to heavily. However this comes with its own problems. For example the, I might find that I end up needing observers or delegates for an increasing amount of events needed to observe to extend behaviour can increase very easily. Sobehaviours until I end up needing observers/listeners/delegates for practically every behaviour. One option could be to just have one big listener/delegate for all of the behaviour but then the implementing class ends up with lots of empty methods etc.

Then I might try another patternapproach but there are just as many issues with that. Then the next one, and the one after etc.


This gets very difficult when each approach seems to have as many problems as any of the others. This leads to a sort of design decision paralysisThis iterative process gets very difficult when each approach seems to have as many problems as any of the others and leads to a sort of design decision paralysis. It is also difficult to accept that the code will end up veryequally problematic regardless of which design pattern or approach is used. This resultsIf I end up in a loss of motivation because "clean" code ceases to be an option sometimes. Are there any approaches to design that can help to minimise this situation does it mean that the problem itself needs to be rethought? Is there an accepted practice for what one shouldWhat do in a situation likeothers do when they encounter this situation?

Edit: There seems to be a number of interpretations of the question that I want to clear up:

  • I have taken OOP out of the question completely because it turns out that it is not actually specific to OOP, plus it is too easy to misinterpret some of the comments I made in passing about OOP.
  • Some have claimed I should take an iterative approach and try different patterns, or that I should discard a pattern when it ceases to work. This is the process I intended to refer to in the first place. I thought this was clear from the example but I could have made it clearer, so I've edited the question to do so.

How do you navigate OOP grey areas to avoid design decision paralysis?

So probably like many, I subscribe to the OOP philosophy of programming, although I would like to think not overly-strongly. I often find myself running into headaches with OOP problems in which, for example, there is some desired design pattern that I would like to implement because it's more OO (and therefore more maintainable, scaleable etc.). Very often there is some caveat which makes it difficult to implement the pattern without some kind of ugly and less OO workaround. I can very easily end up going around in circles between patterns/approaches because almost all of them have some very significant caveats in real-world situations.


Example:

I'll give you a recent example. Let's say I want to use composition over inheritance. I might refactor the code but then find that there are some contexts where the superclass/baseclass simply needs to call functionality on the subclass. So then I start having to implement a half delegate/observer pattern and half composition pattern so that the superclass can delegate behaviour or so that the subclass can observe superclass events. Then the class is less scaleable and maintainable because its unclear how it should be extended, also it is tricky to extend existing listeners/delegates. Also information isn't hidden well because one starts needing to know the implementation to see how to extend the superclass (unless you use comments very extensively).

So after this one might opt to simply just use observers or delegates. However this comes with its own problems. For example the amount of events needed to observe to extend behaviour can increase very easily. So I end up needing observers/listeners/delegates for practically every behaviour. One option could be to just have one big listener/delegate for all of the behaviour but then the implementing class ends up with lots of empty methods etc.

Then I might try another pattern but there are just as many issues with that. Then the next one, and the one after etc.


This gets very difficult when each approach seems to have as many problems as any of the others. This leads to a sort of design decision paralysis. It is also difficult to accept that the code will end up very problematic regardless of which design pattern or approach is used. This results in a loss of motivation because "clean" code ceases to be an option sometimes. Are there any approaches to design that can help to minimise this problem? Is there an accepted practice for what one should do in a situation like this?

How do you avoid endlessly iterating through equally sub-optimal design patterns or approaches?

So probably like many, I often find myself running into headaches with design problems in which, for example, there is some design pattern/approach that seems to intuitively fit the problem and has desired benefits. Very often there is some caveat which makes it difficult to implement the pattern/approach without some kind of work around which then negates the benefit of the pattern/approach. I can very easily end up iterating through many patterns/approaches because predictably almost all of them have some very significant caveats in real-world situations.


Example:

I'll give you a hypothetical example based loosely on a real one I recently encountered. Let's say I want to use composition over inheritance because inheritance hierarchies have hindered the scaleability of the code in the past. I might refactor the code but then find that there are some contexts where the superclass/baseclass simply needs to call functionality on the subclass, despite attempts to avoid it.

The next best approach seems to be implementing a half delegate/observer pattern and half composition pattern so that the superclass can delegate behaviour or so that the subclass can observe superclass events. Then the class is less scaleable and maintainable because its unclear how it should be extended, also it is tricky to extend existing listeners/delegates. Also information isn't hidden well because one starts needing to know the implementation to see how to extend the superclass (unless you use comments very extensively).

So after this I might opt to simply just use observers or delegates completely to get away from the drawbacks that comes with mixing up the approaches to heavily. However this comes with its own problems. For example, I might find that I end up needing observers or delegates for an increasing amount of behaviours until I end up needing observers/delegates for practically every behaviour. One option could be to just have one big listener/delegate for all of the behaviour but then the implementing class ends up with lots of empty methods etc.

Then I might try another approach but there are just as many issues with that. Then the next one, and the one after etc.


This iterative process gets very difficult when each approach seems to have as many problems as any of the others and leads to a sort of design decision paralysis. It is also difficult to accept that the code will end up equally problematic regardless of which design pattern or approach is used. If I end up in this situation does it mean that the problem itself needs to be rethought? What do others do when they encounter this situation?

Edit: There seems to be a number of interpretations of the question that I want to clear up:

  • I have taken OOP out of the question completely because it turns out that it is not actually specific to OOP, plus it is too easy to misinterpret some of the comments I made in passing about OOP.
  • Some have claimed I should take an iterative approach and try different patterns, or that I should discard a pattern when it ceases to work. This is the process I intended to refer to in the first place. I thought this was clear from the example but I could have made it clearer, so I've edited the question to do so.
made the example more clearly demarcated
Source Link
Jonathan
  • 211
  • 1
  • 6

So probably like many, I subscribe to the OOP philosophy of programming, although I would like to think not overly-strongly. I often find myself running into headaches with OOP problems in which, for example, there is some desired design pattern that I would like to implement because it's more OO (and therefore more maintainable, scaleable etc.). Very often there is some caveat which makes it difficult to implement the pattern without some kind of ugly and less OO workaround. I can very easily end up going around in circles between patterns/approaches because almost all of them have some very significant caveats in real-world situations.


Example:

I'll give you a recent example. Let's say I want to use composition over inheritance. I might refactor the code but then find that there are some contexts where the superclass/baseclass simply needs to call functionality on the subclass. So then I start having to implement a half delegate/observer pattern and half composition pattern so that the superclass can delegate behaviour or so that the subclass can observe superclass events. Then the class is less scaleable and maintainable because its unclear how it should be extended, also it is tricky to extend existing listeners/delegates. Also information isn't hidden well because one starts needing to know the implementation to see how to extend the superclass (unless you use comments very extensively).

So after this one might opt to simply just use observers or delegates. However this comes with its own problems. For example the amount of events needed to observe to extend behaviour can increase very easily. So I end up needing observers/listeners/delegates for practically every behaviour. One option could be to just have one big listener/delegate for all of the behaviour but then the implementing class ends up with lots of empty methods etc.

Then I might try another pattern but there are just as many issues with that. Then the next one, and the one after etc.

 

This gets very difficult when each approach seems to have as many problems as any of the others. This leads to a sort of design decision paralysis. It is also difficult to accept that the code will end up very problematic regardless of which design pattern or approach is used. This results in a loss of motivation because "clean" code ceases to be an option sometimes. Are there any approaches to design that can help to minimise this problem? Is there an accepted practice for what one should do in a situation like this?

So probably like many, I subscribe to the OOP philosophy of programming, although I would like to think not overly-strongly. I often find myself running into headaches with OOP problems in which, for example, there is some desired design pattern that I would like to implement because it's more OO (and therefore more maintainable, scaleable etc.). Very often there is some caveat which makes it difficult to implement the pattern without some kind of ugly and less OO workaround. I can very easily end up going around in circles between patterns/approaches because almost all of them have some very significant caveats in real-world situations.

I'll give you a recent example. Let's say I want to use composition over inheritance. I might refactor the code but then find that there are some contexts where the superclass/baseclass simply needs to call functionality on the subclass. So then I start having to implement a half delegate/observer pattern and half composition pattern so that the superclass can delegate behaviour or so that the subclass can observe superclass events. Then the class is less scaleable and maintainable because its unclear how it should be extended, also it is tricky to extend existing listeners/delegates. Also information isn't hidden well because one starts needing to know the implementation to see how to extend the superclass (unless you use comments very extensively).

So after this one might opt to simply just use observers or delegates. However this comes with its own problems. For example the amount of events needed to observe to extend behaviour can increase very easily. So I end up needing observers/listeners/delegates for practically every behaviour. One option could be to just have one big listener/delegate for all of the behaviour but then the implementing class ends up with lots of empty methods etc.

Then I might try another pattern but there are just as many issues with that. Then the next one, and the one after etc.

This gets very difficult when each approach seems to have as many problems as any of the others. This leads to a sort of design decision paralysis. It is also difficult to accept that the code will end up very problematic regardless of which design pattern or approach is used. This results in a loss of motivation because "clean" code ceases to be an option sometimes. Are there any approaches to design that can help to minimise this problem? Is there an accepted practice for what one should do in a situation like this?

So probably like many, I subscribe to the OOP philosophy of programming, although I would like to think not overly-strongly. I often find myself running into headaches with OOP problems in which, for example, there is some desired design pattern that I would like to implement because it's more OO (and therefore more maintainable, scaleable etc.). Very often there is some caveat which makes it difficult to implement the pattern without some kind of ugly and less OO workaround. I can very easily end up going around in circles between patterns/approaches because almost all of them have some very significant caveats in real-world situations.


Example:

I'll give you a recent example. Let's say I want to use composition over inheritance. I might refactor the code but then find that there are some contexts where the superclass/baseclass simply needs to call functionality on the subclass. So then I start having to implement a half delegate/observer pattern and half composition pattern so that the superclass can delegate behaviour or so that the subclass can observe superclass events. Then the class is less scaleable and maintainable because its unclear how it should be extended, also it is tricky to extend existing listeners/delegates. Also information isn't hidden well because one starts needing to know the implementation to see how to extend the superclass (unless you use comments very extensively).

So after this one might opt to simply just use observers or delegates. However this comes with its own problems. For example the amount of events needed to observe to extend behaviour can increase very easily. So I end up needing observers/listeners/delegates for practically every behaviour. One option could be to just have one big listener/delegate for all of the behaviour but then the implementing class ends up with lots of empty methods etc.

Then I might try another pattern but there are just as many issues with that. Then the next one, and the one after etc.

 

This gets very difficult when each approach seems to have as many problems as any of the others. This leads to a sort of design decision paralysis. It is also difficult to accept that the code will end up very problematic regardless of which design pattern or approach is used. This results in a loss of motivation because "clean" code ceases to be an option sometimes. Are there any approaches to design that can help to minimise this problem? Is there an accepted practice for what one should do in a situation like this?

Source Link
Jonathan
  • 211
  • 1
  • 6
Loading