Solved

Switch Statement Alternative?

Posted on 2013-11-16
19
332 Views
Last Modified: 2013-11-19
I have a situation where I have 2 possible classes and each inheriting the same thing except for one class is inheriting 1 more structure.

Something like:
Class A:    
Race
Name
Sex
Age
Location
Status
ValStat

Open in new window


Class B:    
Race
Name
Sex
Age
Location
Status
ValStat
Nationality

Open in new window

Both A and B are inheriting the Race, Name, Age, Sex, Status, Location and ValStat. B is defining the Nationality

Now I have a validation check based on the Class A or Class B object and I base it off an Enum meaning I have Class A associated with like Local and Class B with like International and it's based off the Location.

So, on the validaton if I check the enum and it's Local then I run the local validation check and if Internional then I base it off a validation. In some of the validations they are the same like associated with Age or Sex. Meaning whether local or International they are still validated.

Right now, I have switch statements.

So I check the Status in the switch and then I check the enum then perform the validation off the enum.
switch (Status)
{
    case Citizen:

         switch (A.Location)
         {

              case West:

                   do common validation using the A object
                   Update the A object ValStat
              break;

              case East:

                  do common validation using the B object
                  do international validation
                  Update the B object ValStat
              break; 
         }
         break;

    case Alien:

         switch (A.Location)
         {

              case West:

                   do alien confirmation using the A object
                   Update the A object ValStat
              break;

              case East:

                  do alien confirmation using the B object 
                  do internation validation
                  Update the B object ValStat
              break; 
         }
         break;

}

Open in new window

Now, from a readability standpoint I do not see it that bad but from a maintenance/update standpoint if I have to add something in the common validation they I need to do it in 2 places. Or if I need to change the Update for the ValStat then I need to do it in 4.

Class A and Class B are inheriting already and is used throught the system already so in that sense I cannot change them as that would cause a lot of regression testing.  

Is there another or better way to do something like this? If not, I may just have to accept this and the maintentane risk vs the readability risk but I want to exhaust first.
0
Comment
Question by:davism
  • 8
  • 7
  • 3
19 Comments
 
LVL 51

Expert Comment

by:Julian Hansen
Comment Utility
Why not add the validation to the classes themselves - have a common validation at a base class level that is overridden and extended in the Class A / Class B level.

Then just invoke the validation by class.
0
 
LVL 1

Author Comment

by:davism
Comment Utility
julianH,

Do you have any example utilizing that switching sample I have above?

Are you talking like an abstract class? Remember, I cannot modify the Class A or Class B because of the existing use. Even to the extent of specifying a baseclass.

Is that what you are referring to?
0
 
LVL 51

Expert Comment

by:Julian Hansen
Comment Utility
Remember, I cannot modify the Class A or Class B because of the existing use
Why not?

By extending the class you don't effect existing use?
0
 
LVL 1

Author Comment

by:davism
Comment Utility
Because the regression testing would be an extreme level of effort and no available time. It's been there and proven it's effectiveness and value-add.

I see nor does the team a compelling reason to justify the addition, regression testing (which we all should do - Testing 101), for the small requirement change. Small change associated or compared to existing use.
0
 
LVL 51

Expert Comment

by:Julian Hansen
Comment Utility
That is the right place for it - all you are doing is forcing bad design - having said that.

Where is the validation code running currently - your example code is a bit sketchy - difficult to visualize how you have it hanging together.
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
Comment Utility
I realize that you say you cannot modify your classes, but based on what I read above, I wonder if you might create a new interface that all applicable classes implement. In this way, you are simply adding on new functionality rather than changing the old. Using this new abstraction, you can pass instances of each class around as the interface type rather than the concrete type.
0
 
LVL 1

Author Comment

by:davism
Comment Utility
julianH, true it sounds and appears that it might be the right place for it.  Not necessarily a bad design (and no I wasn't even involved or anything when it was done) but in reality then everything using an inherited class could be called a "bad design" because things could happen later and the cost/benefit would have to be considered. But I cleared stated in the OP:

"Class A and Class B are inheriting already and is used throught the system already so in that sense I cannot change them as that would cause a lot of regression testing. "

kaufmed, what you mention intrigues me. But correct me if I'm wrong but wouldn't that require a change to the existing classes on the definition. Meaning instead of an abstract class then it's an interface. However it might lessen the aspect of regression testing because the regression testing? It would/could be lessoned because of an interface use but the only thing using the interface is the new validation aspects?
0
 
LVL 74

Assisted Solution

by:käµfm³d 👽
käµfm³d   👽 earned 100 total points
Comment Utility
Well, as I mentioned, you would not be changing the existing implementations, per se; rather you would be including additional functionality (it's new, so it should break anything--if you're mindful).

Let's say you have the classes written in this manner:

public abstract class CommonBase
{
    public abstract void DoSomething();
}

public class A : CommonBase
{
    public void DoSomething()
    {
        Console.WriteLine("This is A");
    }
}

public class B : CommonBase
{
    public void DoSomething()
    {
        Console.WriteLine("This is B");
    }
}

Open in new window


Now, if I change the existing implementation of the abstract class, then I might break A and B, yes? But if I add in anything new, the existing implementation is fine (meaning there was no regression). So, I am proposing that you add a new interface definition:

public interface ITheInterface
{
    void NewValidationMethod();
}

Open in new window


...that each class, or even the base class implements:

public abstract class CommonBase : ITheInterface
{
    public abstract void DoSomething();

    public abstract void NewValidationMethod();
}

public class A : CommonBase
{
    public void DoSomething()
    {
        Console.WriteLine("This is A");
    }

    public override void NewValidationMethod()
    {
        Console.WriteLine("Validating A");
    }
}

public class B : CommonBase
{
    public void DoSomething()
    {
        Console.WriteLine("This is B");
    }

    public override void NewValidationMethod()
    {
        Console.WriteLine("Validating B");
    }
}

Open in new window


Disclaimer:  I free-coded the above, so it's not tested for syntactic errors. It should convey the idea, though.

Now I mentioned above that you should be "mindful" of what you are changing. If these new methods you add in manipulate any of the existing state that the class maintains, then you will need to regression test. If the new methods are read-only, or work with their own instance fields, then you shouldn't have any regression.
0
 
LVL 51

Expert Comment

by:Julian Hansen
Comment Utility
You did not answer the bit about where you are currently doing the validation.

Just following on from Kaufmed's post - wether you change the implementation to use the interface or change the class to include an additional method - should not really be that different.

If I change class A from

Class A {
    void doSomething() {
          ....
    }
}

To
Class A {
     void doSomething() {
     ...
     }

    void doSomethingElse() {
    ...
    }
}

Open in new window

The effect on regression testing should be minimal UNLESS the added method interacts with the class in such a way as to change state.

As you are already calling a validation function to validate these classes then the effect should be no different whether this function is a class member or not.

The benefits of including it in the class is that you can implement a different validation for each class but invoke it in the same way.

I am still hazy as to how you are invoking your validation currently - it might be a bit easier to answer the question if you could give more detail on where and how you are invoking it.
0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 1

Author Comment

by:davism
Comment Utility
Understand on the disclaimer.

However, it's still using an abstract class though. But it appears to compound it by adding an interface on to that abstract class.

The regression testing would have to work with any situations whether or not they are read-only. The QA group would not accept that if it's not read-only or not. The mere fact is that it's changing and that is what. Ideally, in a perfect world they wouldn't need to test every possible variation or use of these classes. But the mere fact that the content of the class is then that would justify a regression test. It's akin to changing a DAL that everything uses. It is a big ordeal and if it's not done or done in bits and pieces they it's not providing justice or due-diligence. I cannot disagree with them and that tact as it just makes sense.

I'm getting the sense that there really is no alternative. I know it makes sense on the abstract class but it is what it is and the con's outweigh the pro's here.
0
 
LVL 51

Expert Comment

by:Julian Hansen
Comment Utility
Ok understood - ignore my last post.

I'm getting the sense that there really is no alternative.

There probably is but still interested to know where and how the validation is currently running.
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
Comment Utility
However, it's still using an abstract class though.
I only included an abstract class because I thought that's how you were currently set up. The abstract class is not germane to the point I am making above, which is to create an interface that allows you to treat separate classes as similar references (to the interface type) without manipulating the existing structure (or base structure).

The regression testing would have to work with any situations whether or not they are read-only.
Well any time you are modifying the existing structure, then you would need to regression test. If these new methods modified the private fields that already existed before you added the new methods, then you would need a regression test.

It's akin to changing a DAL that everything uses.
Well, you should aim to write your DAL in such a way that swapping out the DAL has no effect on the other layers. Abstraction (abstract classes and interfaces) are how you achieve this.
0
 
LVL 1

Author Comment

by:davism
Comment Utility
julianH, that is because I'm not following where significance or importance of the validation context would be.  But right now I have it in the switch statements and it's a one-liner like an inline IF based on Age. Or if it's not in the switch statements it would be in the abstract class.

Well any time you are modifying the existing structure, then you would need to regression test. If these new methods modified the private fields that already existed before you added the new methods, then you would need a regression test.

yep, completely agree which is why unless there is a compelling "show-stopper" reason we do not change it and over the years (from what I understand) there has only been 1.

Well, you should aim to write your DAL in such a way that swapping out the DAL has no effect on the other layers. Abstraction (abstract classes and interfaces) are how you achieve this.

Our DAL DOES in fact have that and it makes sense because of the scope of use on the DAL. I was just using it as an example and a poor one at that I realize. My bad. But following along the same lines with a DAL, IF a DAL was comprised of inheritance use all the time (that's the part I didn't mention) then the same situation would apply.
0
 
LVL 51

Accepted Solution

by:
Julian Hansen earned 300 total points
Comment Utility
In that case I would turn your switch statement around.

Keep all the common validation outside of the switch and when checking status only do the international testing there.

So Age and Race etc you keep outside and then when you come to location then do some thing like
if (obj.race != 'caucasian' && ... ) process_validation_failure;
if (obj.age < 10 || obj.age > 99) process_validation_failure
if (obj.status == 'Citizen') {
   if (obj.location == 'East') do_local_east_validation()
   else do_local_west_validation();
}
else {
   if (obj.location == 'East') do_intl_east_validation()
   else do_intl_west_validation();
}

Open in new window


I think that was what the original question was asking was it not. We took a detour to determine why it could not happen in the classes themselves - that was not an option so you wanted to know how to re-order the validation check to make it both readable and maintanable.
0
 
LVL 1

Author Comment

by:davism
Comment Utility
julianH, I think you got somewhere.

I thought putting it in the switch statements were good to associate; never really thought about outside.

I initially had the nested-if's and from my prospective I looked and that and cringed because I viewed that as unreadable. So, I went with the switch statements and that made it, subjectively, a bit more readable but it through the aspect of the maintenance issue.

Let me think about this and consider using methods as you are on some of the if's you have.

Mind you, in a perfect situation, I definitely would pursued using the abstract classes; but I just cannot for the reasons I mentioned. :-(
0
 
LVL 51

Expert Comment

by:Julian Hansen
Comment Utility
My view is that when we model the world we are constrained by the complexity of what we are trying to model. Sometimes code is necessarily complex.

There is only so much you can do without spending more time than is feasible for little gain.
0
 
LVL 1

Author Closing Comment

by:davism
Comment Utility
Thanks guys! julianH, I gave you most of the points and your last comment trended me in the direction that made a little sense considering what I had to work with.

I gave kaufmed some points for the work and chiming in a well.

Thanks guys! Very much appreciated.
0
 
LVL 51

Expert Comment

by:Julian Hansen
Comment Utility
You are welcome - thanks for the points.
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

This article introduced a TextBox that supports transparent background.   Introduction TextBox is the most widely used control component in GUI design. Most GUI controls do not support transparent background and more or less do not have the…
Introduction Hi all and welcome to my first article on Experts Exchange. A while ago, someone asked me if i could do some tutorials on object oriented programming. I decided to do them on C#. Now you may ask me, why's that? Well, one of the re…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now