Many web applications I've contributed in (mostly ASP.NET), need to handle multiple and different user types.
Let's say you have a school portal, which both pupils and teachers use daily. On the front page of the application the users are met with almost the same GUI except some links to some tools only the teachers have access to. Let's say this is a messaging tool. A teacher can have different roles which defines who the teacher can send to.
For example:
Publisher
are allowed to send to everyone in the school.The problem I always get into is that my code is always getting cluttered with if
-statements when handling different user types all over the application. Not only because of the different user types, but also by different business rules. I feel I can't find any way to properly handle different user types.
I guess the concept of roles in ASP.NET kind of solves this, but you would still end up with if
-statements around the application.
My question is: Is there any best-practice on how to handle different users/user types in an application without infecting the code with if
-statements?
You should split these responsibilities (like the sending capabilities of a teacher for example). You can do this by using the strategy pattern.
So a teacher has an extra property Publishing, which serves as an interface. The implementation can have multiple realizations (e.g. NoPublishing for a teacher who does not have publishing functionality, or DefaultPublishing). Each teacher can have its Publishing property set to either NoPublishing or DefaultPublishing. It can even be changed runtime if needed.
An example:
public class Teacher
{
public IPublishing Publishing { get; }
}
interface IPublishing
{
void Send();
}
public NoPublishing : IPublishing
{
public void Send()
{
// Implementatation
}
}
public PublishDefault : IPublishing
{
public void Send()
{
// Send a message the default way
}
}
Create a teacher:
var teacher = new Teacher();
Create a publisher strategy.
var defaultStrategy = new PublishDefault();
Connect them
teacher.Publishing = defaultStrategy;
Now you can send a message by:
teacher.Publishing.Send();
Depending on which Publishing strategy has been connected it will either send nothing or send something the default way.
You only need to instantiate each used Publishing strategy once and reuse it for each Teacher (or even other classes who needs to be able to send).
When you need other publish functionality, just add a new strategy (e.g. SmsPublishing, LetterPublishing etc).
You can even change the strategy on the fly if it is needed (by reassigning the Publishing property).
Why not implementing the interface not directly in Teacher?
(note: I don't have a compiler here, so code is only for explanation purposes).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With