language-agnostic - 干还是不干?关于避免代码重复和保持内聚

标签 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();
        }
    }
}

最佳答案

问题太笼统,无法真正说出来,但作为练习:

假设你抽象它。考虑想要更改生成的 5 行函数的可能原因是什么。您是否希望做出适用于所有用户的更改,或者您是否最终必须编写一个与旧函数略有不同的新函数,每次调用者都有理由想要更改?

如果您想为所有用户更改它,这是一个可行的抽象。现在给它起一个糟糕的名字,你以后可能会想到一个更好的名字。

如果您打算在将来随着代码的发展而将这个函数拆分成许多类似的版本,那么它可能不是一个可行的抽象。您仍然可以编写该函数,但它更像是一个节省代码的“辅助函数”,而不是问题的正式模型的一部分。这不是很令人满意:这种代码量的重复有点令人担忧,因为它表明应该在某处有一个可行的抽象。

也许 5 行中的 4 行可以抽象出来,因为它们更具凝聚力,而第五行恰好与它们在一起。然后你可以编写 2 个新函数:一个是这个新的抽象,另一个只是一个调用新函数然后执行第 5 行的助手。这些函数中的一个可能比另一个有更长的预期使用生命周期。 .

关于language-agnostic - 干还是不干?关于避免代码重复和保持内聚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4178128/

相关文章:

c++ - 我可以使用 decltype() 来避免显式模板实例化中的代码重复吗?

algorithm - 单个 "1"位的 SHA-256 哈希值是多少?

language-agnostic - 如何让非技术人员理解非 UI 问题?

oop - 耦合 - 除了更改方法签名或返回类型之外,更改一个模块如何影响另一个模块?

c# - 有一个只有属性的类可以用于重构目的吗?

java - 我们如何使用类似于 Intellij 的 Netbeans 来查找重复代码?

language-agnostic - 依赖注入(inject)、延迟加载、代理和循环依赖

mysql - 如何最好地组合和优化这两个查询?

SQL 数据库重构工具

go - 防止在 Go 中为 Field-Only 结构重复函数