【发布时间】:2011-05-15 03:35:26
【问题描述】:
我有两种不同类型的用户,我已将它们映射到两个 Java 类 UserWheel 和 UserSea,它们有一个共同的抽象超类,称为 用户。为这些用户类型保存的数据大致相同,但行为不同。
然后我创建了一个名为 UserCollection 的抽象类,其中包含派生类 UserWheelCollection 和 UserSeaCollection 来搜索子用户或加载子用户。
然后我在 UserCollection 类中添加了一个带有签名的抽象方法
public abstract List<User> listAllSubusers()
这是因为实现会有所不同。创建的每个用户将是一个 UserWheel 或一个 UserSea,具体取决于调用哪个方法,但所有其余的实现都完全不同。
然后我想向 UserCollection 添加一个带有签名 public User loadById(int idUser) 的新方法。在这种情况下,除了返回的用户将是 UserWheel 或 UserSea 的实例之外,实现将是相同的。在这种情况下,由于代码重复,我不愿意在基类中使用抽象方法。
我可以用 instanceof 检查 UserCollection 的具体类并创建一个适当的子类,但它似乎不是面向对象的并且违反了开闭原则。
另一个想法是向 UserCollection 添加一个抽象方法 createNewUser() 并在子类中添加具体实现以返回一个新实例,因此基类将只调用此 createNewUser() 方法。
您认为第二条路径有意义吗?或者你会以不同的方式和方式来组织事情?
更新。目前的情况是:
abstract class User
public String getAddress()
public void setAddress()
...
class UserSea extends User
class UserWheel extends User
abstract class UserCollection
protected abstract User createNewUser();
public abstract List<User> listAllSubUsers();
public User loadById(int idUser) {
User newUser = createNewUser();
//populate it
return newUser;
}
class UserSeaCollection
protected User createNewUser() {
return new UserSea();
}
public List<User> listAllSubusers()
class UserWheelCollection
protected User createNewUser() {
return new UserWheel();
}
public List<User> listAllSubusers()
按照trashgod的建议,我试图理解策略模式,这是我的第一次尝试:
interface SubuserManagement
List<User> listAllSubUsers();
...
interface UserCrud
void create();
User readById(int idUser);
void update();
void delete();
class UserSeaCollection implements SubUserManagement, UserCrud
private SubUserManagement subuserBehavior = new SubUserManagementSeaImplementation();
private UserCrud userCrudBehavior = new UserCrud();
void create {
subUserBehavior.create();
}
...
class UserWheelCollection implements SubUserManagement, UserCrud
...
class SubUserManagementWheelImplementation implements SubUserManagement
List<User> listAllSubUsers();
class SubUserManagementSeaImplementation implements SubUserManagement
List<User> listAllSubUsers();
class UserCrudImplementation implements UserCrud //only 1 implementation
void create();
User readById(int idUser);
void update();
void delete();
在第一次尝试中,我创建了 UserCollectionWheel 和 UserCollectionSea,它们不再共享一个公共超类,而是实现了相同的接口。实际的实现是在外部类中。
现在 UserCollectionWheel 和 UserCollectionSea 实际上是同一个类,只是我分配给它们的行为不同。或者,我可以只用 setter 编写一个类:
UserCollection userColl = new UserCollection();
userColl.setSubUserBehavior(new SubUserManagementSeaImplementation());
userColl.setCrudBehavior(new UserCrud());
但是初始化会很麻烦,特别是如果我有更多的行为类。那么我做错了什么?如何正确组织?
更新 2:我写了一个 blog post 与我已经实现的设计。
【问题讨论】:
-
我不了解驱动这种结构的外部力量以及您通过这样做试图实现的目标。您能否更详细地描述您正在尝试做的事情,但避免使用编程术语和特定数据结构的描述。而是描述这两个用户做了什么,使用你的程序的人从他们那里得到了什么。
-
@Hovercraft,谢谢,我会尝试一下,简要说明。这些用户会做很多事情,比如创建/更新/删除用户,创建/更新/删除子用户,发送不同的激活邮件(委托)等等。由于这是一个 stackoverflow 问题,我试图将范围缩小到两个操作:列出所有子用户并按 id 加载单个用户。例如列出所有子用户根据用户类型有一个完全不同的查询,所以我想使用继承来映射不同的行为。
标签: java oop design-patterns