干还是不干?避免代码重复和保持凝聚力

luk*_*m00 7 language-agnostic refactoring code-duplication

我有一个关于代码重复和重构的问题,希望它不是太笼统.假设您有一小段代码(~5行),这是一系列函数调用- 不是很低级别.这个代码在几个地方重复,因此在这里提取方法可能是个好主意.然而,在这个特定的例子中,这种新功能将遭受低内聚(其中,其中,通过难以找到该功能的良好名称而表现出来).原因可能是因为这个重复的代码只是更大算法的一部分 - 并且很难将其划分为命名良好的步骤.

在这种情况下你会建议什么?

编辑:

我想将问题保持在一般水平,以便更多人可能发现它有用,但显然最好用一些代码示例来支持它.这个例子可能不是有史以来最好的(它有很多种方式闻名),但我希望它能完成它的工作:

class SocketAction {

    private static class AlwaysCreateSessionLoginHandler extends LoginHandler {
        @Override
        protected void onLoginCorrect(SocketAction socketAction) throws IllegalAccessException, IOException {
            Server.checkAllowedDeviceCount(socketAction._sess.getDeviceID());
            socketAction.registerSession();
            socketAction._sess.runApplication();
        }
    }

    private static class AutoConnectAnyDeviceLoginHandler extends LoginHandler {
        @Override
        protected void onLoginCorrect(SocketAction socketAction) throws IllegalAccessException, IOException {
            if (Server.isUserRegistered(socketAction._sess.getUserLogin())) {
                Log.logSysInfo("Session autoconnect - acquiring list of action threads...");
                String[] sa = Server.getSessionList(socketAction._sess.getUserID());
                Log.logSysInfo("Session autoconnect - list of action threads acquired.");
                for (int i = 0; i < sa.length; i += 7) {
                    socketAction.abandonCommThreads();
                    Server.attachSocketToSession(sa[i + 1], socketAction._commSendThread.getSock());
                    return;
                }
            }
            Server.checkAllowedDeviceCount(socketAction._sess.getDeviceID());
            socketAction.registerSession();
            socketAction._sess.runApplication();
        }
    }

    private static class OnlyNewSessionLoginHandler extends LoginHandler {
        @Override
        protected void onLoginCorrect(SocketAction socketAction) throws IllegalAccessException, IOException {
            socketAction.killOldSessionsForUser();
            Server.checkAllowedDeviceCount(socketAction._sess.getDeviceID());
            socketAction.registerSession();
            socketAction._sess.runApplication();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*sop 8

问题太笼统,不能说,但作为一项练习:

假设你抽象它.想想想要改变最终的5行功能的可能原因是什么.你想让可能会让适用于所有用户的更改,或者你会最终不得不写一个新的功能,这是稍有不同,从旧的,每个呼叫者一些具有有理由要更改时间?

如果你想为所有用户改变它,它是一个可行的抽象.现在给它一个不好的名字,你可能会想到一个更好的名字.

如果你要结束掉拆分此功能分为许多类似的版本为您的代码在未来的发展,这可能不是一个可行的抽象.您仍然可以编写该函数,但它更像是一个代码保存的"辅助函数",而不是正式问题模型的一部分.这是不是很满意:此数量的代码的重复是有点令人担忧,因为这表明存在在某处有一个可行的抽象.

也许5行4可以抽象出来的,因为他们是更有凝聚力和第五行只是恰巧被在院里与他们挂.然后,你可以写两个新的功能:一个是这个新的抽象,而对方只是调用新功能的帮助,然后执行第5行这些功能之一然后可能比其他更长的预计使用寿命.. .