在虚拟商店用户类场景中是否应使用Java抽象工厂或工厂方法?
问题
我正在做虚拟商店的Java编码练习,现有设计如下:
- 父类
User,属性包含id、email、password - 三个子类:
Administrator:可管理商品目录与客户列表,额外属性有first name、last name、salary、phone numberCustomer:从目录选品,系统生成清单供Employee处理付款,额外属性有first name、last name、dateOfBirth、profession、residenceEmployee:协助客户付款,无问题时给客户发邮件,额外属性为salary
现在需要创建各类用户实例,但我觉得直接用子类的参数化构造方法就够了,完全没必要用抽象工厂/工厂方法这类创建型模式。想请教:为什么要在这个场景下用这些模式?以及具体该怎么实现?
附上当前的代码示例:
public class User{ private Integer id; private String email; private String password; public User(Integer id, String email, String password) { this.id = id; this.email = email; this.password = password; } // getter-setter }
public class Customer extends User{ private String firstName; private String lastName; private String dateOfBirth; private String profession; private String residence; public Customer(Integer id, String email, String password, String firstName, String lastName, String dateOfBirth, String profession, String residence) { super(id, email, password); this.firstName= firstName; this.lastName= lastName; this.dateOfBirth= dateOfBirth; this.profession = profession; this.residence = residence; } // getter-setter }
Administrator和Employee的实现逻辑类似,仅属性不同
解答
为什么要使用工厂模式?
你当前的写法在小场景下没问题,但如果后续需求迭代,工厂模式的优势会很明显:
- 封装创建逻辑:如果后续要给所有用户实例加统一初始化逻辑(比如密码加密、自动生成唯一id、校验邮箱格式),直接改工厂就行,不用去每个子类的构造方法里逐一修改。
- 解耦创建与使用:调用方不用记清每个子类的构造参数顺序和细节,只需要告诉工厂要创建什么类型的用户,减少代码耦合。
- 扩展性强:如果新增
Guest这类用户类型,只需要加对应的工厂实现,不用修改现有调用代码,符合开闭原则。 - 避免参数臃肿:像
Customer的构造有8个参数,很容易传错顺序,工厂可以配合建造者模式,让实例创建更清晰。
怎么实现?
方案1:工厂方法模式
可以用单工厂类根据类型创建实例,也可以为每种用户单独建工厂类,这里先讲最常用的单工厂实现:
// 定义用户类型枚举 enum UserType { CUSTOMER, ADMINISTRATOR, EMPLOYEE } public class UserFactory { public static User createUser(UserType type, Map<String, Object> params) { Integer id = (Integer) params.get("id"); String email = (String) params.get("email"); String password = (String) params.get("password"); // 统一处理:比如加密密码 String encryptedPwd = encryptPassword(password); switch(type) { case CUSTOMER: return new Customer(id, email, encryptedPwd, (String) params.get("firstName"), (String) params.get("lastName"), (String) params.get("dateOfBirth"), (String) params.get("profession"), (String) params.get("residence")); case ADMINISTRATOR: return new Administrator(id, email, encryptedPwd, (String) params.get("firstName"), (String) params.get("lastName"), (Double) params.get("salary"), (String) params.get("phoneNumber")); case EMPLOYEE: return new Employee(id, email, encryptedPwd, (Double) params.get("salary")); default: throw new IllegalArgumentException("未知用户类型"); } } // 模拟密码加密逻辑 private static String encryptPassword(String password) { return password + "_encrypted"; } }
调用示例:
Map<String, Object> customerParams = new HashMap<>(); customerParams.put("id", 1); customerParams.put("email", "customer@shop.com"); customerParams.put("password", "123456"); customerParams.put("firstName", "John"); customerParams.put("lastName", "Doe"); customerParams.put("dateOfBirth", "1990-01-01"); customerParams.put("profession", "Engineer"); customerParams.put("residence", "New York"); User customer = UserFactory.createUser(UserType.CUSTOMER, customerParams);
方案2:抽象工厂模式
如果后续用户还需要配套的服务(比如不同用户对应不同的权限处理器),可以用抽象工厂把用户创建和配套服务创建绑定:
// 抽象工厂接口 public interface UserFactory { User createUser(Map<String, Object> params); PermissionHandler createPermissionHandler(); } // Customer专属工厂 public class CustomerFactory implements UserFactory { @Override public User createUser(Map<String, Object> params) { Integer id = (Integer) params.get("id"); String email = (String) params.get("email"); String encryptedPwd = encryptPassword((String) params.get("password")); return new Customer(id, email, encryptedPwd, (String) params.get("firstName"), (String) params.get("lastName"), (String) params.get("dateOfBirth"), (String) params.get("profession"), (String) params.get("residence")); } @Override public PermissionHandler createPermissionHandler() { return new CustomerPermissionHandler(); } private String encryptPassword(String password) { return password + "_encrypted"; } } // Administrator专属工厂 public class AdministratorFactory implements UserFactory { @Override public User createUser(Map<String, Object> params) { // 同理实现管理员实例的创建逻辑 return new Administrator(...); } @Override public PermissionHandler createPermissionHandler() { return new AdminPermissionHandler(); } } // 权限处理器接口 interface PermissionHandler { boolean canManageCatalog(); } // 客户权限处理器 class CustomerPermissionHandler implements PermissionHandler { @Override public boolean canManageCatalog() { return false; // 客户只能看目录,不能修改 } } // 管理员权限处理器 class AdminPermissionHandler implements PermissionHandler { @Override public boolean canManageCatalog() { return true; // 管理员可以修改目录 } }
调用示例:
UserFactory customerFactory = new CustomerFactory(); User customer = customerFactory.createUser(customerParams); PermissionHandler customerPerm = customerFactory.createPermissionHandler();
总结
如果只是当前的简单练习场景,直接用构造方法完全没问题;但如果项目会迭代扩展,工厂模式能帮你规避后续很多维护上的麻烦,提升代码的可维护性和扩展性。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

