开发者

Builder or some other pattern to always create instance in valid state

I have a very complicated setup of objects and each selection along the way limits or expands options available. I would hate to throw exceptions or to create invalid instance of t开发者_StackOverflow中文版he object. So, I want to limit options (methods available to invoke) when building an instance based on the previous method input paramters. For example if I have some rules that say if user is of type "A" then allow it to be added to roles otherwise if it is of type "B" ask for location and if location is in specific zip code ... You get the idea

Is this possible with anonymous methos, types, whatever

user type A

UserBuilder builder = new UserBuilder
builer.Build().ForType("A").WithRoles(rolesList);

user type B

UserBuilder builder = new UserBuilder
builer.Build().ForType("B").WithLocations(locationList);

Update: So basically my question is, Is there a way to limit all other public method options from the api, except for the valid ones based on the state of the object.


Yes, this would be theoretically possible. (Though anonymous methods/types would not, most likely, be involved.)

However, usage will be a bit of a nightmare. Unfortunately, if you put these types of restrictions in using a fluent interface, you pretty much need to know the rules to understand how to "build" the type.

I would much prefer making specialized user subclasses for your different types of users. Have the constructors of each subclass require the parameters necessary for them to be initialized correctly, and expose methods and properties as required.

This way, you just make the appropriate user:

UserA userA = new UserA(rolesList); // This requires roles to construct
UserB userB = new UserB(locationList); // This requires locations to construct


You can do something like the code below, which is obviously just a concept. The problem is that you have to code the method calls for each type in the chain to maintain the fluent interface.

class Program
{
    static void Main(string[] args)
    {
        var builder = new UserBuilder();
        builder.BuildTypeA().WithRoles("a,b");
        builder.BuildTypeB().WithLocations("c,d");
    }
}

public abstract class User {}
public class UserA : User {}
public class UserB : User {}

public class UserBuilder
{
    public UserABuilder BuildTypeA() { return new UserABuilder(); }
    public UserBBuilder BuildTypeB() { return new UserBBuilder(); }
}

public class UserABuilder
{
    public UserABuilder WithRoles(string roles)
    {
        // add roles
        return this;
    }
}

public class UserBBuilder
{
    public UserBBuilder WithLocations(string locations)
    {
        // add locations
        return this;
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜