6

This is a question more about best practices/design patterns than regexps.

In short I have 3 values: from, to and the value I want to change. From has to match one of several patterns:

XX.X
>XX.X
>=XX.X
<XX.X
<=XX.X
XX.X-XX.X

Whereas To has to be a decimal number. Depending on what value is given in From I have to check whether a value I want to change satisfies the From condition. For example the user inputs "From: >100.00 To: 150.00" means that every value greater than 100.00 should be changed.

The regexp itself isn't a problem. The thing is if I match the whole From against one regexp and it passes I still need to check which option was inputted - this will generate at least 5 IFs in my code and every time I want to add another option I will need to add another IF - not cool. Same thing if I were to create 5 Patterns.

Now I have a HashMap which holds a pattern as the key and a ValueMatcher as the value. When a user inputs a From value then I match it in a loop against every key in that map and if it matches then I use the corresponding ValueMatcher to actually check if the value that I want to change satisfies the "From" value.

This aproach on the other hand requires me to have a HashMap with all the possibilities, a ValueMatcher interface and 5 implementations each with only 1 short "matches" methode. I think it sure is better than the IFs, but still looks like an exaggerated solution.

Is there any other way to do it? Or is this how I actually should do it? I really regret that we can't hold methods in a HashMap/pass them as arguments because then I'd only have 1 class with all the matching methodes and store them in a HashMap.

Mateusz Dymczyk
  • 14,969
  • 10
  • 59
  • 94
  • I ran into a similar situation myself and went with the HashMap. I do wish Java would support First-Class Functions. – Poindexter Aug 23 '11 at 16:13

2 Answers2

2

How about a chain of responsibility.

Each ValueMatcher object exactly one From/To rule and a reference to the next ValueMatcher in the chain. Each ValueMatcher has a method which examines a candidate and either transaforms it or passes it on to the next in the chain.

This way adding a new rule is a trivial extension and the controlling code just passes the candidate to the first member of the chain.

djna
  • 54,992
  • 14
  • 74
  • 117
  • Hm but wouldn't it be the same as the 5 IFs in my code? I mean first I'd have to use the first ValueMatcher and check whether the From value matches it this would be the first if, then I'd have to go to the next Matcher etc. Each matcher would mean 1 if. I guess my solution is also a bunch of "ifs" but "hidden" as a HashMap. – Mateusz Dymczyk Aug 23 '11 at 14:27
  • There will be the same number of ifs, but they occur in a very regular way, each ValueMatcher goes "If (for me) do it else pass it on. You don't end up with an every growing pile of if statements. As your rules are not completely regular I don't see any alternative to having specific ifs, we just need to structure them in some clean way. – djna Aug 23 '11 at 15:24
0

a ValueMatcher interface and 5 implementations each with only 1 short "matches" methode. I think it sure is better than the IFs, but still looks like an exaggerated solution.

Well, for something as simple as evaluating a number against an operator and a limit value, couldn't you just write one slightly more generic ValueMatcher which has a limit value and an operator as its parameters? It would then be pretty easy to add 5 instances of this ValueMatcher with a few combinations of >, >=, etc.

EDIT: Removed non Java stuff... sorry about that.

Daniel B
  • 2,877
  • 18
  • 18
  • 1
    I wish I could - unfortunately Java doesn't provide delegates. The only way to get something similar working would probably be to use reflection and I really don't want to do that. – Mateusz Dymczyk Aug 23 '11 at 14:19
  • I think I could but I first would have to check which option was inputted and based on that get the corresponding operators and values (some options have only 1 value, some have 2). Don't really see how I could do it without ifs. – Mateusz Dymczyk Aug 23 '11 at 14:29