avoid instanceof in Java

前端 未结 9 2280
清歌不尽
清歌不尽 2021-02-12 20:40

I have been told at some stage at university (and have subsequently read in upteen places) that using instanceof should only be used as a \'last resort\'. With this

9条回答
  •  野趣味
    野趣味 (楼主)
    2021-02-12 20:52

    I have another suggestion of a way to avoid instanceof.

    Unless you are using a generic factory, at the moment when you create a GameObject you know what concrete type it is. So what you can do is pass any GameGroups you create an observable object, and allow them to add listeners to it. It would work like this:

    public class Game {
        private void makeAGameGroup() {
            mGameObjects.add(new GameGroup(mUITweenManagerInformer));
        }
    
        private void allocateUITweenManager() {
            mUITweenManagerInformer.fire(mUITweenManager);
        }
    
        private class OurUITweenManagerInformer extends UITweenManagerInformer {
            private ArrayList listeners;
    
            public void addUITweenManagerListener(UITweenManagerListener l) {
                listeners.add(l);
            }
    
            public void fire(UITweenManager next) {
                for (UITweenManagerListener l : listeners)
                    l.changed(next);
            }
        }
        private OurUITweenManagerInformer mUITweenManagerInformer = new OurUITweenManagerInformer();
    }
    
    public interface UITweenManagerInformer {
        public void addUITweenManagerListener(UITweenManagerListener l);
    }
    
    public interface UITweenManagerListener {
        public void changed(UITweenManager next);
    }
    

    What draws me to this solution is:

    • Because a UITweenManagerInformer is a constructor parameter to GameGoup, you cannot forget to pass it one, whereas with an instance method you might forget to call it.

    • It makes intuitive sense to me that information that an object needs (like the way a GameGroup needs knowledge of the current UITweenManager) should be passed as a constructor parameter -- I like to think of these as prerequisites for an object existing. If you don't have knowledge of the current UITweenManager, you shouldn't create a GameGroup, and this solution enforces that.

    • instanceof is never used.

提交回复
热议问题