假设我在系统中有两个类:
public class User {
public int getId() {
// implementation
}
// other methods
}
public class Room {
public int getId() {
//implementation
}
public void addUser(User user) {
int userId = user.getId();
// uses userId
}
// other methods
}
然后我意识到这些类的客户端(在系统的不同部分)永远不需要知道Id。所以我应用ISP来提取接口:
public interface User {
// other methods
}
public interface Room {
void addUser(User user);
// other methods
}
并尝试使用ManagedUser和ManagedRoom实现它们。然后发生了一件令人不快的事情:
public class ManagedRoom implements Room {
@Override
public void addUser(User user) {
int userId = user.getId(); // Oops! Cannot get id here.
}
// other methods
}
所以我想知道这里的设计是什么。而且,我是否正确理解了ISP?
答案 0 :(得分:2)
也许您可以定义另一个界面,例如Entity
,如下:
public interface Entity {
int getId();
void setId(int id);
}
public interface User extends Entity {
...
}
public interface Room extends Entity {
...
}
答案 1 :(得分:0)
接受
ISP声明:
Clients should not be forced to depend on methods that they do not use.
ISP涉及重要特征 - 内聚和耦合。
理想情况下,您的组件必须高度定制。它提高了代码的健壮性和可维护性。
执行ISP会为您提供以下奖励:
High cohesion - better understandability, robustness
Low coupling - better maintainability, high resistance to changes
并且,您可以在http://www.oodesign.com/interface-segregation-principle.html
学习样本ISP答案 2 :(得分:0)
我们假设为了完成进入特定房间,只需要用户ID。这至少是您在示例中传递给用户的唯一消息。 我建议要求用户而不是用户:
interface Room {
public void enter(String userID);
}
现在为了让具体的用户进入一个房间你会有一些东西:
class ManagedUser implements User {
public void enterRoom(Room room) {
//provide an ID of some sort to the room
//particular to ManagedUser world
room.enter(myID);
}
}
当然,您可以拥有一个抽象对象用户,允许进入抽象房等。请注意,具体房间可能更新数据库的事实与此级别无关。
class ManagedRoom implements Room {
public void enter(String userID) {
//store userID entering this room in whichever way you see fit
}
}
所以最后进入一个房间会是这样的:
class EnterRoomsGame {
public void play(User user, Room room) {
user.enterRoom(room);
}
}
答案 3 :(得分:0)
在不知道您的用例的情况下很难提出建议。但也许你
我的意思是,提供特定领域的方法(具有"商业意义")并且这个问题可能解决了。例如,如果这是一个MMORPG,你就可以逃脱:
addUser()
因此,Room
和public interface User {
void leaveNorth();
void leaveSouth();
void leaveEast();
void leaveWest();
}
不一定需要相互引用,至少不在界面中。
作为第二种方法,系统的不同部分不一定需要相同的概念"一个User
和Room
。这就是埃里克·埃文斯称之为“有限上下文”的内容。来自Martin Fowler的Here is an article关于它。