【问题标题】:Create complex class with factory and builder使用工厂和构建器创建复杂的类
【发布时间】:2018-08-31 06:36:09
【问题描述】:

背景: 我构建了一个用于在网上购物的类图。 为了创建具有拖曳类型(golden-User 和 silver-User)的用户界面,我使用工厂模式。
但是 User 类变得非常复杂。

如何通过 bulider 创建此类,另一方面,指定用户类型(例如工厂)的能力将保留在类名上 (将帮助我通过多态而不是 if&else 来识别哪种类型)

【问题讨论】:

  • 您能否包含示例代码以说明客户端代码如何调用此类工厂/构建器,更准确地描述问题所在以及您到目前为止尝试的内容?

标签: oop design-patterns class-design class-diagram


【解决方案1】:

装饰器模式是一个简单的解决方案:

public class Main {

    public static void main(String[] args) {

        User silverUser = new UserDecorator(new SilverUser("Kyriakos", "Georgiopoulos"));
        User goldenUser = new UserDecorator(new GoldenUser("GoldenUser firstName", "GoldenUser lastName"));
        User nullUser = new UserDecorator(null);

        System.out.println(silverUser.firstName() + " " + silverUser.lastName() + " is " + silverUser.type());
        System.out.println(goldenUser.firstName() + " " + goldenUser.lastName() + " is " + goldenUser.type());
        System.out.println(nullUser.firstName() + " " + nullUser.lastName() + " is " + nullUser.type());
         }
}

interface User {
    String firstName();

    String lastName();

    String type();
}

class SilverUser implements User {

    private final String firstName;
    private final String lastName;

    SilverUser(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String firstName() {
        return firstName;
    }

    public String lastName() {
        return lastName;
    }

    public String type() {
        return "SilverUser ";
    }
}

class GoldenUser implements User {

    private final String firstName;
    private final String lastName;

    GoldenUser(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String firstName() {
        return firstName;
    }

    public String lastName() {
        return lastName;
    }

    public String type() {
        return "GoldenUser ";
    }
}

class UserDecorator implements User {
    private final User user;
    
    UserDecorator(User user){
        this.user = user;
    }
    
    public String firstName() {
        return user != null && user.firstName() != null && user.firstName().length() > 0 ?
                user.firstName() : "";
    }

    public String lastName() {
        return user != null && user.lastName() != null && user.lastName().length() > 0 ?
                user.lastName() : "";
    }
    
    public String type() {
        return user != null ? user.type() : "NullPointerException";
    }
}

【讨论】:

    【解决方案2】:

    两种模式的意图不同:Factory 创建一个对象实例(可以容纳更多其他类实例),而 Builder 的目标是逐步创建对象并减少重载的构造函数。 例如(使用 java sn-ps):

    工厂方法

    用户界面:

    public interface User {
    }
    

    GoldUser 类:

    class GoldUser implements User {
      // ... field declarations
      // Ctor
      GoldUser(fields...){}
      // ... methods 
    }
    

    SilverUser 类:

    class SilverUser implement User {
      // ... field declarations
      // Ctor
      SilverUser(fields...){}
      // ... methods 
    }
    

    用户工厂类:

    public class UserFactory {
      // ... user versions
      public static int GoldUser = 0;
      public static int SilverUser = 1;
    
      // ... private Ctor because we don't want to instantiate this class - only in this example
      private UserFactory (){}
    
      // ... creating appropriate User instance
      public static User createUser(int userType){
         switch (userType){
            case GoldUser: return new GoldUser;
            case SilverUser: return new SilverUser;
            default throw new WrongUserTypeException("Wrong User Type");
         }
      }
    }
    

    在你的其他班级:

    // ... code stuff here
    User user=UserFactory.createUser(1); // will return new SilverUser instance
    // ... other code stuff here
    

    建造者模式

    如果你的类中有很多字段并且只有其中一些是强制性的,那么你不必创建很多构造函数,一个构造函数就足够了:

    class UserBuilder{
    private static Service_A serviceA;  // required
    private static Service_B serviceB;  // required
    private static Service_C serviceC;
    private static Service_D serviceD;
    private static Service_E serviceE;
    
    // since this builder is singleton
    private static UserBuilder builderInstance = new UserBuilder();
    private UserBuilder () {};
    
    public static UserBuilder getBuilderInstance (Service_A service_A, Service_B service_B){
    serviceA = service_A;
    serviceB = service_B;
    serviceC = null; 
    serviceD = null;
    serviceE = null;
    return builderInstance;
    }
    
    public static UserBuilder addServiceC (Service_C service_C) {
      serviceC = service_C;
      return builderInstance; 
    }
    
    public static UserBuilder addServiceD (Service_D service_D) {
      serviceC = service_D;
      return builderInstance; 
    }
    
    public static UserBuilder addServiceE (Service_E service_E) {
      serviceE = service_E;
      return builderInstance; 
    }
    
    public static User build(){
      return new User (serviceA, ServiceB, ServiceC, ServiceD, ServiceE);
    }
    

    稍后您可以构建自定义用户:

    UserBuilder aUserBuilder = UserBuilder.getBuilderInstance(aServiceA, aServiceB);
    // ... other stuff
        aUserBuilder.addServiceE(aServiceE);
    ///... more stuff
     User aUser= aUSerBuilder.addServiceC(aServiceC)
        .build(); // will return the fresh built User instance
    

    希望能帮到你! 问候, 铯

    【讨论】:

      【解决方案3】:

      在这种特殊情况下,您不应该使用 Factory 来创建同一类的不同实例。它可用于创建一种常见抽象的不同实现。尝试实现 IUser 接口。然后通过两个类来实现这个接口:GoldenUser 和 SilverUser。您的工厂将创建 GoldenUser 或 SilverUser 的实例并将其作为 IUser 返回。此外,您可以创建 User 抽象类,而不是接口 IUser,该类将由 GoldenUser 和 SilverUser 继承。

      【讨论】:

        猜你喜欢
        • 2020-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-06
        • 1970-01-01
        相关资源
        最近更新 更多