天天看點

如何利用回調模式去解決問題

在軟體的設計/實作過程中,我的同僚經常會遇到這樣一個場景:需要在一個可重用的、大範圍的方法中調用若幹個不确定的方法或一系列不确定的操作。在這種情況下,我經常建議他們使用“回調”這種技巧去解決問題。

回調模式和接口、抽象這兩個概念是緊密相關的,在這裡簡要的說明一下。

接口(Interface):說明類該做什麼而不指定如何去做。抽象(abstract)的道理也大緻如此。

回調,這個模式一般是這麼定義的:在回調模式中你可以指定當一個特定時間發生時回調對象上的方法。這句話是不是很不好了解?那麼舉些例子就清楚了,例:java swing中ActionListener的接口監聽機制,類似的API還有java.swing.JOptionPane、java.swing.Timer、java.awt.Tookit……有點明白了吧,簡單的說:所謂回調模式,一般就是方法回調——定義個抽象的(先不實作的)方法先行調用,然後在具體的使用中對此抽象方法進行實作,以供前面“回頭調用”,此之所謂回調,如是然也。

有個實際的例子,這是在工作中我設計的一個基于回調模式的小工具,它可以根據指定的批量數(batchSize)來處理一個較大的泛型數組(Object[]),這可以用在廣域網絡計算、Web服務的場景中,因為如果一次讓遠端網絡服務端處理大量的資料,必然會存在效率低下、響應不及的情況,如果分批次處理再傳輸的話,那樣效果就會好的多,響應效率也能讓人接受。

package com.tibco.plugin.salesforce.util;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.Collections;

import java.util.List;

/** *//**

 * Batch Operation Tool

 *

 * @serialData 2007

 */

public abstract class BatchOperation ...{

    /** *//**

     * Sign means no batchSize, all do once.

     */

    public final static int SIGN_NO_BATCH_SIZE = -1;

    private final Object[] ALL;

    private final int SUM;

     * Call back method, define your operation by imple it.

     *

     * @param params

     * @return

     * @throws Exception

    protected abstract Object[] operate(Object[] params) throws Exception;

     * @param all

     *            all data

    public BatchOperation(Object[] all) ...{

        if (all != null && all.length > 0) ...{

            this.ALL = all;

            this.SUM = all.length;

        } else ...{

            this.ALL = null;

            this.SUM = 0;

        }

    }

     * You can use it to do batch operation.

     * @param batchSize

     *            batch operation size

     * @return operation results

    public Object[] doBatch(int batchSize) throws Exception ...{

        if (SUM == 0)

            return null;

        Object[] results = null;

        if (batchSize == SIGN_NO_BATCH_SIZE) ...{

            // no batch

            results = operate(ALL);

            // has batch

            final List<Object> LIST_ALL = Collections.unmodifiableList(Arrays

                    .asList(ALL));

            int remain = SUM;

            int times = 0;

            List<Object> resultsList = new ArrayList<Object>(SUM);

            while (remain > 0) ...{

                int theBatch = remain > batchSize ? batchSize : remain;

                Object[] batch = LIST_ALL.subList(batchSize * times,

                        batchSize * times + theBatch).toArray(

                        new Object[theBatch]);

                Collections.addAll(resultsList, operate(batch));

                times++;

                remain = remain - batchSize;

            }

            results = resultsList.toArray(new Object[SUM]);

        return results;

}

如果看了以上的内容還是不明白回調模式或這個工具如何使用,那麼我們可以讨論……

     本文轉自胡奇 51CTO部落格,原文連結:http://blog.51cto.com/huqicto/280904,如需轉載請自行聯系原作者