-1
public void AccessPermissions(User user)
{
   if (user.Age >= 18)
   {
      if (user.IsRegistred)
      {
         if (user.IsPowerfull)
         {
             AcessGrantLevel3();
         }
         else
         {
             AccessGrantLevel2();
         }
      }
      else
      {
         AccessGrantLevel1();
      }
   }
   else
   {
       AcceessDenied();
   }
}

According to code metrics measurement this function is very bad and according to the clean code developemnt this function is bad for testing. What can I do to make Code Metrics and TDD happy? Is nested If statements always bad?

9
  • 7
    This questions belongs on codereview.stackexchange.com. Commented Sep 6, 2013 at 18:45
  • 1
    Show the link if this true?! Commented Sep 6, 2013 at 18:47
  • 2
    There are a lot better ways to build this. Factory or Strategy pattern would a better way to go. Commented Sep 6, 2013 at 18:47
  • 3
    I would suggest you make AccessGrantLevel() a function with a parameter that can be 0 (Access Denied) up to 3 (Registered & Powerful Commented Sep 6, 2013 at 18:47
  • 1
    @Sparky this sounds very good and good for SOLID can you make a small example for me please? Commented Sep 6, 2013 at 18:49

5 Answers 5

3
public void AccessPermissions(User user)
{
    if(user.Age<18)
    {
        AccessDenied();
        return;
    }
    if(user.IsPowerfull && user.IsRegistered)
    {
        AccessGrantLevel3();
        return;
    }
    if(user.IsRegistered)
    {
        AccessGrantLevel2();
        return;
    }
    AccessGrantLevel1();
    return;
}
Sign up to request clarification or add additional context in comments.

1 Comment

This misses braces { ... } or else it won't work.
2

You can flatten the logic like this:

public void AccessPermissions(User user)
{
    if (user.Age < 18)
    {
        AcceessDenied();
    }
    else if (!user.IsRegistred)
    {
        AccessGrantLevel1();
    }
    else if (!user.IsPowerfull)
    {
        AcessGrantLevel2();
    }
    else
    {
        AccessGrantLevel3();
    }
}

Comments

2

It can easily be re-written without nesting.

public void AccessPermissions(User user)
{
   if (user.Age < 18)
   {
       AcceessDenied();
   }
   else if (!user.IsRegistred)
   {
       AccessGrantLevel1();
   }
   else if (user.IsPowerfull)
   {
       AcessGrantLevel3();
   }
   else
   {
       AccessGrantLevel2();
   }
}

2 Comments

Duplicate of what I wrote 30 seconds prior ... =/
The "another answer has been posted" bottom bar popped up just as I clicked submit. Thems the breaks.
0

This is a matter of preference, but most people consider nested if statements to be less readable and harder to maintain, because the code that is to be executed is far away from the statement that caused it.

By reversing the condition of the If statement, you can move the execution logic closer to the condition. consider:

public void AccessPermissions(User user)
{
    if (!(user.Age >= 18))
    {
        AcccessDenied();
    }
    else if (!user.IsRegistered)
    {
        AccessGrantLevel1();
    }
    else if (!user.IsPowerfull)
    {
        AccessGrantLevel2();
    }
    else
    {
        AccessGrantLevel3();
    }
}

Ultimately, any of the multiple examples on this page of other approaches would work with a bit of tweaking... the concept still stands that your goal should be to reduce or eliminate nesting by inverting your conditions.

6 Comments

Loving this: "Update coming to illustrate a better approach."
I made the post but needed a minute to type out the code logic, between the post and the update 2 other people posted the same thing :)
So every user should be granted level3 access? Oops.
I am not sure, but I think if(!user.Age >= 18) will error out without a parentheses if(!(user.Age >= 18))
@AndrewCounts still won't work, you need to use else if or put return statements in each block. Otherwise someone who is not powerful and is not registered will have both AccessGrantLevel1() and AccessGrantLevel2() called.
|
-1

Here is one approach

public void AccessPermissions(User user)
{
    int UserLevel = 0;

UserLevel += (user.Age>=18) ? 1:0;      // Add 1 if user is over 18
UserLevel += (user.IsIsRegistred) ? 1:0;    // If registered, add another 1
UserLevel += (user.IsPowerFull) ? 1:0;      // Add another 1 if powerful

AccessGrantLevel( UserLevel );
}

11 Comments

That is not good, as someone who is under 18 but is registered will have the same user level as someone who is over 18 but not registered.
This methodology has the potential to suddenly break completely if the access level system gets any more complicated. What's wrong with simply mapping levels to an enum and passing that in?
@BassamAlugili It really isn't. This method makes no sense. It works for this particular instance but is totally unmaintainable and unscalable. This is a hack.
I agree, this is an example of one approach, but I put it together more to demonstrate, not to provide actual.
AntP, it is not bad code, it simply encourages encapsulation of the AccessGrantLevel() into a function, rather than a series of individual function calls. The code above focused on determining the parameter and let's the function do the work. I would not suggest it for more complex condition sets, but for small sets like described, it is a reasonable approach..
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.