Создать сложный класс с фабрикой и застройщиком - PullRequest
0 голосов
/ 31 августа 2018

фон: Я строю диаграмму классов для покупок в сети. Для создания пользовательского интерфейса с типом буксировки (Golden-User и Silver-User) я использую фабричный шаблон.
Но класс User стал очень сложным.

Как я могу создать этот класс с помощью bulider и, с другой стороны, возможность указать тип пользователя, такой как фабрика, останется в имени класса (поможет мне узнать, какой тип - по полиморфизму, а не по if & else)

Ответы [ 3 ]

0 голосов
/ 31 августа 2018

Назначение двух шаблонов различно: в то время как Factory создает экземпляр объекта (который может содержать больше экземпляров других классов), цель Builder состоит в том, чтобы шаг за шагом создавать объекты и сокращать перегруженные конструкторы. Например (с фрагментами Java):

Заводской метод

интерфейс для пользователя:

public interface User {
}

GoldUser class:

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

Надеюсь, я смогу вам помочь! С Уважением, Cs

0 голосов
/ 31 августа 2018

Шаблон Decorator представляет собой простое решение:

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";
    }
}
0 голосов
/ 31 августа 2018

В этом конкретном случае вы не должны использовать Factory для создания разных экземпляров одного и того же класса. Его можно использовать для создания разных реализаций одной общей абстракции. Попробуйте реализовать интерфейс IUser. Затем реализуйте этот интерфейс двумя классами: GoldenUser и SilverUser. Ваша фабрика создаст экземпляр GoldenUser или SilverUser и вернет его как IUser. Также вместо интерфейса IUser вы, вероятно, могли бы создать абстрактный класс User, который будет наследоваться GoldenUser и SilverUser.

...