Refactoring long if - else if - else with shared objects

I am looking for a way to reorganize the if / else if / else statement, which also has a bit of nesting. Blocks also use quite a few common objects. My goal is to split the code separately into manageable units, extracted for different classes, and make it pluggable if I need to cover a new condition.

Here is some dummy code to illustrate:

List<ValidationResult> validationResults = new ...; Inspector inspector = commonInspector; bool additionalOp = commonFlag; HashSet<Thing> thingsToCheck = theThings; foreach (var thing in thingsToCheck) { if (IsCandy(thing) && thing.IsWrapped && thing.IsHard) { var inspected = inspector.Inspect(thing.Value); if (inspected != thing.Value) { validationResults.Add(new ...); if (additionalOp) { thing.Taste(); } } } else if (IsChocolate(thing)) { var sweet = (Sweet)thing; List<BadCalories> badCalories; while (var calorie in sweet.Calories) { if (calorie.IsGood) continue; badCalories.Add(calorie); } foreach (var badCal in badCalories) { var inspected = inspector.Inspect(badCal.Value); if (inspected != badCal.Value) { validationResults.Add(new ...); if (additionalOp) { badCal.Taste(); } } } } else { if(thing ...) else if (thing ...) } 

I read a bunch of articles / SO-messages of various patterns / practices that can be applied, but the code dependencies make it difficult for me to use these concepts. It doesn’t help that I look at the code too carefully for some time, so it’s hard to break out of microcontrol into the bird’s eye.

+6
source share
4 answers

You can break blocks of large volume into separate functions.

 if(IsHardWrappedCandy(thing)) ValidateHardWrappedCandy(thing); else if (IsChocolateCandy(thing)) ValidateChocolateCandy(thing); 

There is also interitance where you have to create candy classes and encapsulate behavior:

 public abstract class CandyBase { public abstract void Validate(); } public class HardWrappedCandy : CandyBase { public override void Validate() { // TODO: Validation logic } } 

Then your code will look like this:

 foreach(var candy in candies) candy.Validate(); 

Of course, you need to standardize the parameters, etc., but you get this idea.

Read the book Clean Code, she has many great ideas on how to reorganize. http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882

+6
source

You must create an interface for all of your “things” that announce the various checks that must be performed.

Then your “things” should implement the interface in such a way that you can invoke checks without worrying about what the actual type of implementation is.

 //Interface public interface ICheck { bool Check1(); } //Class public Chocolate : ICheck { public bool Check1() { //logic goes here } } 

Greetings

0
source

It looks like you are trying to convey general information from thing to inspector . To do this, you need methods:

  • Get objects to check.
  • Inspect them

So, let's define two interfaces:

One that can be used to scan objects.

 interface IInspectable { string Value { get; } void Taste(); // And any other methods that need to be called while inspecting } 

and another that can be used to retrieve all the objects from the thing that need to be checked.

 interface IThing { IEnumerable<IInspectable> GetStuffForInspection(); } 

we can implement our classes

 class Candy : IThing, IInspectable { public IEnumerable<IInspectable> GetStuffForInspection() { if (IsWrapped && IsHard) yield return this; } public String Value { ... } public void Taste() { ... } } class Chocolate : Sweet, IThing { public IEnumerable<IInspectable> GetStuffForInspection() { Calories.Where(c => !c.IsGood); } } class Calorie : IInspectable { public String Value { ... } public void Taste() { ... } } 

allowing you to delete all if statements

 foreach (var thing in thingsToCheck) { foreach (var inspectable in thing.GetStuffForInspection()) { var inspected = inspector.Inspect(inspectable.Value); if (inspected != inspectable.Value) { validationResults.Add(new ...); if (additionalOp) { inspectable.Taste(); } } } } 
0
source

This is a strategy template.

http://www.oodesign.com/strategy-pattern.html

You can do something like this:

 List<ValidationResult> validationResults = new ...; Inspector inspector = commonInspector; bool additionalOp = commonFlag; HashSet<IThing> thingsToCheck = theThings; foreach (IThing thing in thingsToCheck) { thing.Validate(inspector); } 

...

 public interface IThing { void Validate(Inspector inspector, ...); } public abstract CandyBase : IThing { public abstract void Validate(Inspector inspector); } public HardWrappedCandy : CandyBase { public override void Validate(Inspector inspector) { // HardWrappedCandy validation logic here var inspected = inspector.Inspect(this); ... } } public Chocolate : IThing { public void Validate(Inspector inspector) { // Chocolate validation logic here... } } public SomethingElseInTheFuture: IThing { public void Validate(Inspector inspector) { // SomethingElseInTheFuture validation logic here... } } 
0
source

All Articles