jlang
jlang

Reputation: 1057

Simplify a typical(?) conditional construct

I frequently saw (and sometimes written myself) constructs like:

if(A || B)
{
    var sharedValue = ...;
    if(A)
    {
      // do stuff with sharedValue
    }
    else
    {
      // do other stuff with sharedValue 
    }
}

Real example:

switch (e.Key)
{
   /* 
    * Don't mind the switch, since it can be simply converted into:
    * if(e.Key == Key.Left || e.Key == Key.Right) { ... }
    */
   case Key.Left: 
   case Key.Right:
       var container = containerFromData(data);
       if (e.Key == Key.Left)
       {
          this.TryNavigateBackward(container);
       }
       else
       {
          this.TryNavigateForward(container);
       }
}

I really feel like I'm missing something, so there must be a better (simpler, less verbose) way to describe that, but couldn't come up with an idea. This question maybe somewhat bound to the programming language one use (I'm currently in C#), but are there any constructs out there, being able to simplify the given example?

Note: I'm aware of the ternary conditional operator a ? b : c, but this (at least in C#) only works when retrieving values and putting them into variables. The example above wants to actually do different (maybe complex) things with a shared Value.

Upvotes: 1

Views: 35

Answers (1)

Patrick87
Patrick87

Reputation: 28302

Since I don't see any other suggestions, I'll throw some out and see whether they're what you're looking for.

First, if OOP is on the table, inheritance can represent this sort of shared behavior. What you would do is encapsulate the shared, A-specific and B-specific behavior in classes Shared, ASpecific and BSpecific, where ASpecific and BSpecific inherit from Shared. Then, if either A or B, you spin up an instance of either ASpecific or BSpecific, respectively, and then treat it as an instance of Shared. If you have conditions C, D, etc. that don't use the shared thing, you'd have possibly another parent class called Base and you'd have CBase, DBase inheriting from Base, Shared inheriting from Base, and spin up an instance depending on the condition and treat the result as an instance of Base.

Second, you could use inversion of control by passing in A-specific and B-specific behaviors to a shared method when shared stuff is required. You could use OOP for this or pure functional programming. Going with the latter (since the former is similar to the above solution and maybe not as good), you'd have a shared function that takes function f as an argument. The function f would have a signature that requires the shared object be passed in. Then, if A, call shared with a function (pointer or anonymous inline) that does the A-specific stuff to the shared object passed into it; otherwise, if B, call shared with a function that does the B-specific stuff to the shared object passed into it.

If all you really want to avoid is nesting, you could also bring the if (A || B) { … } stuff out and make it spin up shared which is declared but not instantiated in a higher scope; then, later, check A and B separately and know that in those cases shared will have the required setup from earlier.

Upvotes: 1

Related Questions