尽量减少class级中的代码重复?

我正在使用下面的类通过使用套接字发送数据到我们的消息队列以同步的方式或异步的方式,如下所示。

到目前为止,我在下面的课程中复制了很多代码。 我有以下5个方法用于同步或异步发送数据,我相信可能有更好的方法来重写这些方法。

public class SendRecord { private final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2); private final Cache cache = CacheBuilder .newBuilder() .maximumSize(2000000) .concurrencyLevel(100).build(); private static class Holder { private static final SendRecord INSTANCE = new SendRecord(); } public static SendRecord getInstance() { return Holder.INSTANCE; } private SendRecord() { executorService.scheduleAtFixedRate(new Runnable() { @Override public void run() { handleRetry(); } }, 0, 1, TimeUnit.SECONDS); } private void handleRetry() { List messages = new ArrayList(cache.asMap().values()); for (PendingMessage message : messages) { if (message.hasExpired()) { if (message.shouldRetry()) { message.markResent(); doSendAsync(message); } else { cache.invalidate(message.getAddress()); } } } } // called by multiple threads concurrently public boolean sendAsync(final long address, final byte[] encodedRecords) { PendingMessage m = new PendingMessage(address, encodedRecords, true); cache.put(address, m); return doSendAsync(m); } // called by above method and also by handleRetry method private boolean doSendAsync(final PendingMessage pendingMessage) { Optional liveSocket = SocketManager.getInstance().getNextSocket(); ZMsg msg = new ZMsg(); msg.add(pendingMessage.getEncodedRecords()); try { // this returns instantly return msg.send(liveSocket.get().getSocket()); } finally { msg.destroy(); } } // called by send method below private boolean doSendAsync(final PendingMessage pendingMessage, final Socket socket) { ZMsg msg = new ZMsg(); msg.add(pendingMessage.getEncodedRecords()); try { // this returns instantly return msg.send(socket); } finally { msg.destroy(); } } // called by multiple threads to send data synchronously without passing socket public boolean send(final long address, final byte[] encodedRecords) { PendingMessage m = new PendingMessage(address, encodedRecords, false); cache.put(address, m); try { if (doSendAsync(m)) { return m.waitForAck(); } return false; } finally { cache.invalidate(address); } } // called by a threads to send data synchronously but with socket as the parameter public boolean send(final long address, final byte[] encodedRecords, final Socket socket) { PendingMessage m = new PendingMessage(address, encodedRecords, false); cache.put(address, m); try { if (doSendAsync(m, socket)) { return m.waitForAck(); } return false; } finally { cache.invalidate(address); } } public void handleAckReceived(final long address) { PendingMessage record = cache.getIfPresent(address); if (record != null) { record.ackReceived(); cache.invalidate(address); } } } 

有没有更好的方法来重写上述方法?

乍一看,你可以使用“提取方法”重构几次。

这段代码重复:

 ZMsg msg = new ZMsg(); msg.add(pendingMessage.getEncodedRecords()); try { // this returns instantly return msg.send(liveSocket.get().getSocket()); } finally { msg.destroy(); } 

所以做一些像私人无效sendMsg()出来。 此代码也重复

 PendingMessage m = new PendingMessage(address, encodedRecords, false); cache.put(address, m); try { if (doSendAsync(m, socket)) { return m.waitForAck(); } return false; } finally { cache.invalidate(address); } 

所以再制作一个方法

总的来说,有一本关于重构的经典而优秀的书https://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672

有两种方法可以减少Java代码。

  1. 切换到Kotlin。

您可以在java项目中使用单个kotlin文件或转换整个项目。 Eclipse和Android Studio可以将整个项目从Java转换为Kotlin。

您可以在Kotlin类中使用Java类,反之亦然。

在Kotlin中,您可以使用默认参数。

 fun doSendAsync(pendingMessage: PendingMessage, socket: Socket = SocketManager.getInstance().getNextSocket().get().getSocket()) 

如果套接字通过,它将被使用。 否则,将使用SocketManager.getInstance()。getNextSocket()。get()。getSocket()。

这将是你的方法声明

  private boolean doSendAsync(final PendingMessage pendingMessage, final Socket socket) 

  private boolean doSendAsync(final PendingMessage pendingMessage) 

  1. 发送默认属性到更复杂的方法。

如果您想使用Java,请执行以下操作。

  private boolean doSendAsync(final PendingMessage pendingMessage) { return doSendAsync(pendingMessage), SocketManager.getInstance().getNextSocket().get().getSocket()); }