• Post Reply Bookmark Topic Watch Topic
  • New Topic

Which Design Pattern Goes Here?  RSS feed

 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I feel I should know this, but I'm not finding it in my book on Design Patterns. I have some code that looks like this:


In words, methods always and sometimes are almost the same, but have a few differences buried between two otherwise identical blocks of code. This violates DRY and I seem to recall a design pattern that copes with this, but can't remember which one it is.

Anyone remember?
 
K. Tsang
Bartender
Posts: 3648
16
Firefox Browser Java Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
strategy?

Intent
* Define a family of algorithms, encapsulate each one, and make them interchangeable
* Let the algorithm vary independently from clients that use it
 
Junilu Lacar
Sheriff
Posts: 11493
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't recognize any pattern in that. Strategy is an entire pluggable class with a common API, usually defined by an interface or abstract class or a base class that has default behavior. It might fit Template, which is at the method level but that still seems like a stretch.

Why aren't Alpha and Beta code blocks just extracted and calls made to them from always and sometimes? Also, DRY is not necessarily about a character for character comparison as it is about a duplication of an idea. The fact that they are blocks of code that look the same makes them more likely to be duplicates of the same idea though.
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, strategy is the one I was trying to remember. It works, but seems like overkill for this. Here's what I've come up with, so far:


What do you folks think of that?
 
Campbell Ritchie
Marshal
Posts: 56546
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I presume you have some way to initialise that boolean field, otherwise it is completely redundant.
 
Stephan van Hulst
Saloon Keeper
Posts: 7987
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, it's public, which is kinda bad in its own right.
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:Well, it's public, which is kinda bad in its own right.

As usual, Stephan has the answer, and I agree with his criticism. As I often do, I've stripped my example of all but what I think is necessary to explain the issue I'm dealing with. In reality, control would have a setter, or else it would be private and managed internally by the class.
 
Junilu Lacar
Sheriff
Posts: 11493
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stevens Miller wrote:Yes, strategy is the one I was trying to remember. It works, but seems like overkill for this. Here's what I've come up with, so far:

If it works and you're ok with it, that's fine but it's not Strategy. Strategy would be something like this:

And your client code would choose which worker to use based on the state of control

Here, each class encapsulates its strategy for doing whatever "it" is. One of them includes a call to work(), the other one doesn't.
 
Junilu Lacar
Sheriff
Posts: 11493
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you deemed that the value of control needs to be encapsulated somehow, you might also consider refactoring to a Factory that gives you back an appropriate Strategy based on control. That is, Factory knows the different strategies for doing "it", you can tell Factory what control is via a setter or via the parameter to its newWorker() factory method.
 
Liutauras Vilda
Sheriff
Posts: 4918
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Outside your main problem.
I find this signature very confusing, workSometimes along with parameter variable name always, true | false. Might think about better parameter name.
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Junilu Lacar wrote:
Stevens Miller wrote:Yes, strategy is the one I was trying to remember. It works, but seems like overkill for this. Here's what I've come up with, so far:

If it works and you're ok with it, that's fine but it's not Strategy.

Oh, definitely it is not Strategy. It's something I came up with as an alternative, because I think Strategy would be overkill.

Strategy would be something like this:


I don't think that's quite Strategy either, as you've got unnecessary parallelism at Lines 11 & 13 of Worker.doIt, and Lines 24 & 25 of ModifiedWorker.doIt. I believe Strategy would look more like this:


Now the Alpha and Beta blocks only appear once.

Of course, I've got parallelism too, at Line 12 and Line 21, but that's not typical of Strategy. Typically, the body of the work method would not be the same for each implementation of the Work interface, which I believe is the whole point of Strategy: one interface allows for different algorithms to be injected into different instances of a class (if both implementations needed the Gamma block, they could call a common instance of another class that contained that code). That's part of why I am thinking Strategy is overkill here, and the non-Strategy trick(?) I've come up with will get the job done.

But I'm always interested in knowing what my colleagues think of my methods, especially when I find myself using the word "trick" to describe them.

   
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Junilu Lacar wrote:If you deemed that the value of control needs to be encapsulated somehow, you might also consider refactoring to a Factory that gives you back an appropriate Strategy based on control. That is, Factory knows the different strategies for doing "it", you can tell Factory what control is via a setter or via the parameter to its newWorker() factory method.

Hey, that's a good idea for cases where control won't change. I'll keep that one in mind.
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Liutauras Vilda wrote:Outside your main problem.
I find this signature very confusing, workSometimes along with parameter variable name always, true | false. Might think about better parameter name.

Agreed. Any suggestions?
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Oh, just in the for-what-it's-worth department, in my actual code, the condition is coded like this:


Hope that looks a little better.
 
Junilu Lacar
Sheriff
Posts: 11493
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stevens Miller wrote:Oh, just in the for-what-it's-worth department, in my actual code, the condition is coded like this:


Hope that looks a little better.

I'd be inclined to refactor some more. I think I get the condition but it takes a few seconds to parse it out from that formula.

You're basically saying, "if there's a difference or if you don't care whether there's a difference, process the newReading."

I might experiment with moving the condition down into process(newReading) and turn it into a guard clause.

I can't tell what the scope of newReading and oldReading is though so this might be ugly if you're having to reach too far out in the scope to get to these values from deeper down in the call stack.
 
Liutauras Vilda
Sheriff
Posts: 4918
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

That condition would make sense to me if there would be AND operator instead OR.

As it is now, second one is redundant.

If newReading != oldReading is TRUE, then all expresion is true regardless of right operand value.
If newReading != oldReading is FALSE, then it means they are equal, in such case regardlessOfDifference value doesn't make sense as there is no difference.

I might misunderstanding.
 
Junilu Lacar
Sheriff
Posts: 11493
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think Liutauras is on to what was taking me a while to understand the formula.  That != combined with "regardlessOf" is a bit of a brain twister.
 
Liutauras Vilda
Sheriff
Posts: 4918
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Junilu Lacar wrote:I think Liutauras is on to what was taking me a while to understand the formula.  That != combined with "regardlessOf" is a bit of a brain twister.
I think I got it now after you said that. Those two operands are not related, right?

[1] newReading, oldReading and [2] regardlessOfDifference I was trying to merge them into one line story, but it seems they are from different context if I'm not mistaken this time. But that is confusing I'd say.
 
Junilu Lacar
Sheriff
Posts: 11493
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't think it's that they're unrelated because I think they are, actually. There's something implied in "regardsOfDifference" -- in full, the idea is "regardless of whether newReading and oldReading are different" and newReading != oldReading tells you whether or not they are, except the negation and the || is a little harder to wrap your head around. Just the fact that I have to do a double take on the formula makes me want to refactor it.
 
Liutauras Vilda
Sheriff
Posts: 4918
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What puzzles my head are those 2 thinking perspectives:

1. regardlessOfDifference, in the amount of meters readings, i.e.: either differ in 2 kW or 4 kW.
or
2. regardlessOfDifference, that it doesn't matter if there is any difference or not.
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How about this?
 
Junilu Lacar
Sheriff
Posts: 11493
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No mental snag with that for me, except the question "Is there no better name?" 
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Junilu Lacar wrote:No mental snag with that for me, except the question "Is there no better name?" 

I'm a lawyer. I never use a short word when a long one will do. You're the one who tries to proselytize me on the self-documenting code thing. Got any pithier ideas? I agree that regardlessOfDifference kinds of inverts the meaning, but how about just regardless?
or

Trouble I have with those is that they don't connote the notion that sometimes the condition will pass regardless of whether or not there is a difference, and sometimes it won't pass unless there is a difference. I need a name that doesn't suggest one situation or the other but, rather, suggests that we might be in either of two modes.
 
Junilu Lacar
Sheriff
Posts: 11493
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ironically, just regardless makes more sense to me. alwaysForNow also is richer in idea, if that's it's true intent.
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Junilu Lacar wrote:Ironically, just regardless makes more sense to me. alwaysForNow also is richer in idea, if that's it's true intent.

regardless it shall be, then. Appreciate the confab. 
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!