"Broken OOP" 或如何使用 NavigationDrawer 回调

"Broken OOP" or how to use NavigationDrawer callbacks

我正在使用 NavigationDrawer- MaterialDrawer 的自定义实现创建应用程序。这是一个很棒的库,它使用动态添加抽屉到现有的视图层次结构中。
至于我们需要 Navigation Drawer 出现在我们应用程序的所有活动中,我们可以有一个 BasicActivity 抽象 class 来初始化抽屉,设置它并做一些其他类似的基本事情活动。

这是我 BaseActivity.

的部分逻辑
  @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l, IDrawerItem iDrawerItem) {
        Intent intent;
        int itemId = iDrawerItem.getIdentifier();
        if(itemId==getActivityTag()) {
            return;
        }
        switch(itemId){
            case DrawerConstants.PrimaryItemConstants.ALL_CATEGORIES_PAGE_INDEX:
                intent = new Intent(this,CategoryListActivity.class);
                startActivity(intent);
                break;
            case DrawerConstants.PrimaryItemConstants.LOGIN_ITEM_INDEX:
                intent = new Intent(this,LoginScreen.class);
                startActivity(intent);
                break;
        }
    }
    public abstract int getActivityTag();

一切似乎都很好,但一个问题是我们必须了解所有 child 继承的 classes 并在语句中在它们之间切换。
所以parent知道它的children.
我认为就 OOP 而言这是不好的做法。
也许有任何解决方法可以按照设计模式以优雅的方式解决这个问题。

提前致谢。

So parent is aware of its children.

您不必这样做。覆盖 children 处理特定 children 案例的方法,将 super. onItemClick 作为 switch 的默认案例。 parent 必须只处理 children

常见的情况

您可以做的是在 DrawerConstants.PrimaryItemConstants class 中保留 Map 个值,而不是使用 switch-case

class PrimaryItemConstants {

    static private boolean didInit = false;
    static public Map<Integer,Class> classMap = new HashMap<Integer,Class>();

    /** initializes static variables, including classMap. 
    * Can be called multiple times but will only be initialized on first call.
    */
    static public void initialize(){
        if (didInit)return;
        classMap.put(new Integer(ALL_CATEGORIES_PAGE_INDEX),CategoryListActivity.class);
        classMap.put(new Integer(LOGIN_ITEM_INDEX), LoginScreen.class);
    }

}

然后在您的 onItemClick 中,您将从 Map:

获得 class
class BaseActivity {

    /** starts the activity corresponding the the clicked IDrawerItem
    *
    *
    * @throws Exception if itemId does not have a corresponding key in DrawerConstants.PrimaryItemConstants.classMap
    */
    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l, IDrawerItem iDrawerItem) {
        Intent intent;
        int itemId = iDrawerItem.getIdentifier();
        if(itemId==getActivityTag()) {
            return;
        }
        DrawerConstants.PrimaryItemConstants.initialize();
        if (DrawerConstants.PrimaryItemConstants.classMap.contains(new Integer(itemId)){
            intent = new Intent(this,DrawerConstants.PrimaryItemConstants.classMap.get(new Integer(itemId));
            startActivity(intent);
        } else {
            //or whatever you want
            throw new Exception("itemId "+itemId+" not found in classMap");
        }
    }
}