我目前正在为类层次结构建模,因此想要检查是否有人有更好的方法来执行此操作。问题如下:
我有一个菜单项,里面有id和图标。然后我也可以有菜单项,其他子菜单项(但不是同时的图标)。它基本上是子菜单项的容器,但也有id作为真正的菜单项。目前的模型是这样的:
class SubMenuItemOrderNumber{}
class MenuItemTypeId{}
class MenuIconId{}
class MenuIcon{}
interface MenuItemWithoutSubItems{
MenuItemTypeId getTypeId();
List<MenuIcon> getIcons();
}
interface MenuItemWithSubItems{
MenuItemTypeId getTypeId();
Map<SubMenuItemOrderNumber, SubMenuItem> getOrderNumToSubMenuItem();
}
interface SubMenuItem{
SubMenuItemOrderNumber getOrderNum();
List<MenuIcon> getIcons();
}
interface Publishable{
void suspend();
void publish();
}
interface ControllableMenuItemWithoutSubItems extends MenuItemWithoutSubItems, Publishable{
void control(MenuIconId iconId, String iconData);
}
interface ControllableMenuItemWithSubItems extends MenuItemWithSubItems, Publishable{
void control(SubMenuItemOrderNumber orderNum, MenuIconId iconId, String iconData);
}
问题 - 似乎我可以使它更通用。只有我想到的是这种变化:
enum EnumSubMenuItemOrderNumber implements SubMenuItemOrderNumber{
ONLY_IF_MENU_ITEM_WITHOUT_SUB_ITEMS(0);
private int num;
EnumSubMenuItemTypeId(num id){
this.num = num;
}
@Override
public Integer getNum() {
return num;
}
}
class RealSubMenuItemOrderNumber implements SubMenuItemOrderNumber{
private int num;
@Override
public Integer getNum() {
return num;
}
}
interface SubMenuItemOrderNumber{
Integer getNum();
}
class MenuItemTypeId{}
class MenuIconId{}
class MenuIcon{}
interface MenuItem{
MenuItemTypeId getTypeId();
Map<SubMenuItemOrderNumber, SubMenuItem> getOrderNumToSubMenuItem();
}
interface SubMenuItem{
SubMenuItemOrderNumber getOrderNum();
List<MenuIcon> getIcons();
}
interface Publishable{
void suspend();
void publish();
}
interface ControllableMenuItem extends MenuItem, Publishable{
void control(SubMenuItemOrderNumber orderNum, MenuIconId iconId, String iconData);
}
但问题是如果我想要MenuItemWithoutSubItems
我必须MenuItem
而SubMenuItemTypeId
Map
我必须使用EnumSubMenuItemTypeId.ONLY_IF_MENU_ITEM_WITHOUT_SUB_ITEMS
- &gt ;这是我的解决方法。类更简单,但它似乎仍然比需要更复杂。
我可以选择其他任何选项吗?
更新
这是第一个用例的潜在实现:
class DefaultMenuItemWithoutSubItems implements MenuItemWithoutSubItems {
MenuItemTypeId id;
List<MenuIcon> menuIcons;
@Override
public MenuItemTypeId getTypeId() {
return id;
}
@Override
public List<MenuIcon> getIcons() {
return menuIcons;
}
}
class DefaultMenuItemWithSubItems implements MenuItemWithSubItems {
MenuItemTypeId id;
Map<SubMenuItemOrderNumber, SubMenuItem> orderNumToSubMenuItem;
@Override
public MenuItemTypeId getTypeId() {
return id;
}
@Override
public Map<SubMenuItemOrderNumber, SubMenuItem> getOrderNumToSubMenuItem() {
return orderNumToSubMenuItem;
}
}
class DefaultSubMenuItem implements SubMenuItem {
SubMenuItemOrderNumber orderNum;
List<MenuIcon> menuIcons;
@Override
public SubMenuItemOrderNumber getOrderNum() {
return orderNum;
}
@Override
public List<MenuIcon> getIcons() {
return menuIcons;
}
}
class DefaultControllableMenuItemWithoutSubItems implements ControllableMenuItemWithoutSubItems {
MenuItemTypeId id;
List<MenuIcon> menuIcons;
boolean suspended;
@Override
public MenuItemTypeId getTypeId() {
return id;
}
@Override
public List<MenuIcon> getIcons() {
return menuIcons;
}
@Override
public void suspend() {
suspended = true;
}
@Override
public void publish() {
suspended = false;
}
@Override
public void control(MenuIconId iconId, String iconData) {
menuIcons.getById(iconId).replace(new MenuIcon(iconData));
}
}
答案 0 :(得分:0)
这看起来像是在使用复合模式时失败了。 这是复合模式背后的想法:
您有一个要公开的界面。例如:
public interface MenuItem {
MenuItemTypeID getType();
List<MenuIcon> getIcons();
}
接下来,你有一个基本的实现:
class SingleMenuItem implements MenuItem {
private MenuItemTypeID id;
private List<MenuIcon> icons;
public SingleMenuItem(MenuItemTypeID id, List<MenuIcon> icons) {
this.id = id;
this.icons = icons;
}
@Override
public MenuItemTypeID getType() {
return id;
}
@Override
public List<MenuIcon> getIcons() {
return icons;
}
}
这就是魔术。我们还希望有一个分组实现,但复合模式规定它的行为应该与普通的MenuItem完全相同。所以课程看起来像这样:
class MenuItemGroup implements MenuItem {
private MenuItemTypeID id;
private List<MenuItem> subMenuItems;
public MenuItemGroup(MenuItemTypeID id, List<MenuItem> subMenuItems) {
this.id = id;
this.subMenuItems = subMenuItems;
}
@Override
public MenuItemTypeID getType() {
return id;
}
@Override
public List<MenuIcon> getIcons() {
List<MenuIcon> result = new ArrayList<>();
for (MenuItem subItem : subMenuItems) {
result.addAll(subItem.getIcons());
}
return result;
}
}
现在,如果我们有一些MenuItem item
,我们可以获得该菜单项中的所有图标。我们不在乎它是SingleMenuItem
,还是MenuItemGroup
,因为两者都会返回它们包含的所有图标。
请注意,我们还可以拥有一个包含更多组的组,这些组都包含一些SingleMenuItems,或者包含更多MenuItems组的SingleMenuItems组合。我们仍然像任何其他MenuItem一样使用它。
这在你的背景下是多么有用我不知道......