代码之家  ›  专栏  ›  技术社区  ›  epitka

生成器或其他模式,以始终在有效状态下创建实例

  •  0
  • epitka  · 技术社区  · 15 年前

    我有一个非常复杂的对象设置和沿途的每个选择限制或扩展可用的选项。我不想抛出异常或创建对象的无效实例。 因此,我希望在基于前面的方法输入参数构建实例时限制选项(可调用的方法)。例如,如果我有一些规则,说明如果用户是“A”类型,则允许将其添加到角色,否则,如果用户是“B”类型,则请求位置,如果位置在特定的邮政编码中。。。你明白了

    这可能是匿名的方法,类型,无论

    用户类型A

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

    用户类型B

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

    更新: 所以基本上我的问题是,是否有办法限制api中的所有其他公共方法选项,除了基于对象状态的有效方法选项。

    2 回复  |  直到 15 年前
        1
  •  2
  •   Reed Copsey    15 年前

    是的,这在理论上是可能的。(尽管匿名方法/类型很可能不会涉及到。)

    然而,使用将是一个有点梦魇。不幸的是,如果你在使用一个流畅的接口时设置了这些类型的限制,你需要知道规则来理解如何“构建”类型。

    我更喜欢为不同类型的用户创建专门的用户子类。让每个子类的构造函数要求正确初始化它们所需的参数,并根据需要公开方法和属性。

    这样,您就可以让适当的用户:

    UserA userA = new UserA(rolesList); // This requires roles to construct
    UserB userB = new UserB(locationList); // This requires locations to construct
    
        2
  •  0
  •   Jamie Ide    15 年前

    你可以做一些类似下面的代码的事情,这显然只是一个概念。问题是,您必须为链中的每个类型编写方法调用代码,以维护fluent接口。

    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;
        }
    }