Java开关/案例方法推荐长度

Lone_Wanderer

我是一名学生,正在致力于SSL / TLS和JSSE的论文。在oracle提供的实现示例中(位于:http : //docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html#AppA),我找到了实现示例:

   public void doHandshake(SocketChannel socketChannel,
                        SSLEngine     engine,
                        ByteBuffer    myNetData, 
                        ByteBuffer    peerNetData) throws Exception {

    // 2)
    int appBufferSize = engine.getSession().getApplicationBufferSize();
    // 3)
    ByteBuffer myAppData = ByteBuffer.allocate(appBufferSize);
    ByteBuffer peerAppData = ByteBuffer.allocate(appBufferSize);

    // 4)
    engine.beginHandshake();
    SSLEngineResult.HandshakeStatus hs = engine.getHandshakeStatus();

    // 5)
    while (hs != SSLEngineResult.HandshakeStatus.FINISHED
            && hs != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {

        switch (hs) {

            case NEED_UNWRAP:
                // Receive handshaking data from peer
                if (socketChannel.read(peerNetData) < 0) {
                    // The channel has reached end-of-stream
                }

                // Process incoming handshaking data
                peerNetData.flip();
                SSLEngineResult res = engine.unwrap(peerNetData, peerAppData);
                peerNetData.compact();
                hs = res.getHandshakeStatus();

                // Check status
                switch (res.getStatus()) {
                    case OK:
                        // Handle OK status
                        break;

        // Handle other status: BUFFER_UNDERFLOW, BUFFER_OVERFLOW, CLOSED
                    //...
                }
                break;

            case NEED_WRAP:
                // Empty the local network packet buffer.
                myNetData.clear();

                // Generate handshaking data
                res = engine.wrap(myAppData, myNetData);
                hs = res.getHandshakeStatus();

                // Check status
                switch (res.getStatus()) {
                    case OK:
                        myNetData.flip();

                        // Send the handshaking data to peer
                        while (myNetData.hasRemaining()) {
                            socketChannel.write(myNetData);
                        }
                        break;

        // Handle other status:  BUFFER_OVERFLOW, BUFFER_UNDERFLOW, CLOSED
                    //...
                }
                break;

            case NEED_TASK:
                // Handle blocking tasks
                break;

    // Handle other status:  // FINISHED or NOT_HANDSHAKING
            //...
        }
    }

// Processes after handshaking
    //   ...
}

现在,根据我对正确的OOP体系结构的了解,方法不应超过20行,但是我发现Oracle会犯此类基本体系结构错误是很奇怪的。超过20行的任何内容都应分割为单独的方法,但是有例外。我想知道,这是例外之一吗?如果不是,将switch / case方法拆分为较小方法的最佳方法是什么。

幽灵猫

您正在拼凑……不一定属于同一类。

您可以创建一个出色的OOP设计...并且每个方法中仍然有很多代码。

您可以按照干净的代码规则,例如避免任何含有超过方法一个 抽象的单级; 并且最终的设计可能是不好的,并且不是“ OOP”(但是我认为:这很难-如果您遵循所有清晰的代码规则,则会自动创建更好的OOP设计)。

但是,要回答原始问题(这实际上是一个不好的问题;因为它需要基于意见的答案,例如我的):上面的代码至少“一点也不干净”。实际上,我觉得这太可怕了,将“更多”填充到这些枚举案例中的想法对我来说太糟糕了。除此之外,您将不会以这种方式使用枚举-应该使此类“开关”对于客户端代码不可见;相反,您将依赖于多态性;并简单地告诉对某个对象调用某种方法...

到目前为止,我已经在练习干净的代码多年了,发现生成的代码更易于阅读和维护。并在“干净的代码”中;很好,如上所述:您不会在一个方法中放置多个switch语句。每个循环;并且每个中断情况...都将置于各自的方法中。

许多人认为这很疯狂,但经过数月的实践,我发现它确实是“更好”的方法。这确实使我无法创建像您的示例一样无法测试的代码。

并回答您的第二个问题:这确实很难。必须先了解整个设计,然后再将其拆散并重构其元素。但这当然需要您有一套完整的单元/功能测试(这样才能证明所做的更改不会破坏整个过程)。因此,“改进”此类代码的通用方法是:

  1. 了解更改现有软件的真实成本。您不应该仅仅因为“错误的代码”而更改内容。您需要一个充分的(业务)理由来证明更改代码的费用是合理的。
  2. 确保您具有良好的测试。如果有测试,请衡量其覆盖范围(以评估现有测试的“良好”程度)。如果没有测试...开始编写它们。
  3. 测试到位后……开始重新设计,重构并丢弃无法挽救的零件。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章