Modeling "I * but I, too **"

In [ this post ], I am struggling to implement a state template, as @jonp suggests. I donโ€™t quite understand how to use what he wrote, but it leads to the thought that maybe I'm trying to insert a square anchor into a round hole. So my question is:

If I have a visitor to my site that can play several roles, i.e. Usercan be Vendor, Employer, a Advertiser, or all of the above, whether to use inheritance? I stated:

class Vendor : User {}
class Advertiser : User {}

et cetera, but when the user is both a seller and an employer, then instances of different classes really point to the same base object ... I'm not sure if this might work. How to do it?

* update *

Thanks to everyone (all of you get a point (all that I can give)). I pulled my hair out of deep copies using EF, downcasting and state design over the past few days. The role-based approach makes much more sense.

+5
source share
4 answers

This sounds like a situation for which an attribute template (or I call it) would be very appropriate. This is a much more loosely coupled approach than simple inheritance, which can be used to indicate several "behaviors" or in your type cases User. This is really nothing more complicated than an object tagged with another type of object.

User, IList<UserRole> ( List<T>, ). UserRole , VendorRole/AdvertiserRole/etc. , ( ) . , ..

, GetRole<TRole> User ( , User Role ).

: decorator patern, - - , , . , ; .

+4

, , , :

public class User
{
    public Role Role { get; set; }
}

public abstract class Role
{
    abstract void DoRoleSpecificStuff();
}

public class Vendor : Role
{
    public void DoRoleSpecificStuff()
    {
        /* ... */
    }
}

public class Employer : Role
{
    public void DoRoleSpecificStuff()
    {
        /* ... */
    }
}

public class Advertiser : Role
{
    public void DoRoleSpecificStuff()
    {
        /* ... */
    }
}

, :

public IEnumerable<Role> Roles { get; set; }

, , [Flags], , , :

public class User
{
    public Roles Roles { get; set; }
}

[Flags]
public enum Roles
{
    Advertiser = 0x0,
    Employer = 0x1,
    Vendor = 0x2      
}

:

User user = new User
{
    Roles = Roles.Advertiser | Roles.Vendor;
};

, , .

+3

" *, **" . # , .

+2

, , .

, "", . Role.

class User
{
    // all of these may be null if not applicable
    VendorRole VendorRole { get; set; }
    EmployeeRole EmployeeRole { get; set; }
    AdvertiserRole AdvertiserRole { get; set; }
}

If the user can have multiple instances of the same role, a pop-up menu appears:

class User
{
    // all of these may be null if not applicable
    VendorRole VendorRole { get; set; }
    EmployeeRole EmployeeRole { get; set; }
    ICollection<AdvertiserRole> AdvertiserRoles { get; }
}

Alternatively, if there can be a messy bunch of roles, if roles are added dynamically or what you have, you will need a collection and a base type. If you use the Entity Framework, dynamically added roles seem unlikely to me.

class User
{
    ICollection<Role> Roles;
}
+2
source

All Articles