which oo design pattern to use
I need to make a website that will have paid memberships with differing membersip levels. Based on a members level, they will have access to certain features. Is there a design 开发者_如何学编程pattern I could use for this?
I recommend you to read more about design-patterns and OOAD and understand the real purpose of design-patterns. Your application is a very vague case for applying patterns directly onto it. use of patterns depend on various aspects inside the application and not on the application as whole.
Looks like you've just started learning Design patterns. :) The common thing is that when you start learning design patterns, you try to put it everywhere, you try to solve every problem with patterns, and commonly the use of patterns become your goal instead of real problem you're going to solve.
You should forget for a while about design patterns and concentrate on your goal, on what problem you're trying to solve. Then try to solve it, and then perhaps there won't be a need to use any pattern. And perhaps you will realise that something is wrong with the architecture, only then you should think about some refactoring and patterns.
What you're describing has nothing to do with a Object Oriented design pattern, but has to do with access control. If you have tons of hierarchical accesses, I suggest using Role Based Access Control, otherwise stick to ACLs.
Have a look at MVC, .net offer a few examples and something that has worked for us in the past
I suggest avoiding user inheritance and opting for users with flags in the object denoting access rights. OO is good, but it's far easier to work with flags in a simple object, especially when dealing with websites.
In its simplest level, you could have an enumeration called e.g 'Feature' and have the 'Member' class contain a list of 'Features' that he/she is entitled to.
You may decide to store them as flags in the database as someone suggested.
If complexity increases, you can make 'Feature' a full blown class hierarchy e.g. have an interface called IFeature. You can them implement concrete classes for IFeatures. Your 'Member' object will then contain a list of IFeature(s)
What you want is the Chain of Responsibility design pattern.
Here is an example in C#:
using System;
internal sealed class Program
{
private static void Main()
{
// Setup Chain of Responsibility.
Approver larry = new Director();
Approver sam = new VicePresident();
Approver tammy = new President();
larry.Successor = sam;
sam.Successor = tammy;
Purchase purchase;
// Generate and process purchase requests.
purchase = new Purchase {
Number = 2034, Amount = 350.00, Purpose = "Supplies" };
larry.ProcessRequest(purchase);
purchase = new Purchase {
Number = 2035, Amount = 32590.10, Purpose = "Project X" };
larry.ProcessRequest(purchase);
purchase = new Purchase {
Number = 2036, Amount = 122100.00, Purpose = "Project Y" };
larry.ProcessRequest(purchase);
// Wait for user.
Console.ReadKey();
}
}
// Purchase event argument holds purchase info.
internal sealed class PurchaseEventArgs : EventArgs
{
public Purchase Purchase { get; set; }
}
/// <summary>
/// The 'Handler' abstract class.
/// </summary>
internal abstract class Approver
{
// Purchase event .
public event EventHandler<PurchaseEventArgs> Purchase;
// Purchase event handler.
public abstract void PurchaseHandler(Object sender, PurchaseEventArgs e);
// Constructor.
public Approver()
{
Purchase += PurchaseHandler;
}
public void ProcessRequest(Purchase purchase)
{
OnPurchase(new PurchaseEventArgs { Purchase = purchase });
}
// Invoke the Purchase event.
public virtual void OnPurchase(PurchaseEventArgs e)
{
if (Purchase != null)
{
Purchase(this, e);
}
}
// Sets or gets the next approver.
public Approver Successor { get; set; }
}
/// <summary>
/// The 'ConcreteHandler' class.
/// </summary>
internal sealed class Director : Approver
{
public override void PurchaseHandler(Object sender, PurchaseEventArgs e)
{
if (e.Purchase.Amount < 10000.0)
{
Console.WriteLine("{0} approved request# {1}",
this.GetType().Name, e.Purchase.Number);
}
else if (Successor != null)
{
Successor.PurchaseHandler(this, e);
}
}
}
/// <summary>
/// The 'ConcreteHandler' class.
/// </summary>
internal sealed class VicePresident : Approver
{
public override void PurchaseHandler(Object sender, PurchaseEventArgs e)
{
if (e.Purchase.Amount < 25000.0)
{
Console.WriteLine("{0} approved request# {1}",
this.GetType().Name, e.Purchase.Number);
}
else if (Successor != null)
{
Successor.PurchaseHandler(this, e);
}
}
}
/// <summary>
/// The 'ConcreteHandler' class.
/// </summary>
internal sealed class President : Approver
{
public override void PurchaseHandler(Object sender, PurchaseEventArgs e)
{
if (e.Purchase.Amount < 100000.0)
{
Console.WriteLine("{0} approved request# {1}",
sender.GetType().Name, e.Purchase.Number);
}
else if (Successor != null)
{
Successor.PurchaseHandler(this, e);
}
else
{
Console.WriteLine("Request# {0} requires an executive meeting!",
e.Purchase.Number);
}
}
}
/// <summary>
/// Class that holds request details.
/// </summary>
internal sealed class Purchase
{
public Double Amount { get; set; }
public String Purpose { get; set; }
public Int32 Number { get; set; }
}
Hope that helps.
精彩评论