`
huqi
  • 浏览: 93851 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

如何利用回调模式去解决问题

阅读更多

在软件的设计/实现过程中,我的同事经常会遇到这样一个场景:需要在一个可重用的、大范围的方法中调用若干个不确定的方法或一系列不确定的操作。在这种情况下,我经常建议他们使用“回调”这种技巧去解决问题。

回调模式和接口、抽象这两个概念是紧密相关的,在这里简要的说明一下。

接口(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
 *
 * 
@author <a href="mailto:huqiyes@gmail.com">huqi</a>
 * 
@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
     * 
@throws Exception
     
*/

    
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);
        }
 else ...{
            
// 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;
    }

}

如果看了以上的内容还是不明白回调模式或这个工具如何使用,那么我们可以讨论……



分享到:
评论

相关推荐

    微信企业号回调模式设置图解(PHP版).docx

    微信企业号回调模式设置图解(PHP版).docx 分步骤截图,如何设置企业号回调模式。亲测可用!解决回调模式echosstr校验错误问题!

    个人免签监测APP支付宝转账微信模式监听回调源码

    针对由于老旧版本app的各种性能及BUG问题,目前老旧版本的短信监测回调APP版本存在几个通病。1、对于手机性能,网络方面要求高,并发失败。2、app 内存泄露,卡死,掉线问题导致的失败。3、非app扫码付款,导致备注...

    Java基础核心理解+什么是回调即回调机制讲解

    回调是一种双向的调用模式,也就是说,被调用的接口被调用时也会调用对方的接口,这句话可能有点绕,等文章后面举例说明;异步调用是一种类似消息或事件的机制,解决了同步阻塞的问题,举例来讲:A通知B后,他们各走...

    利用接口回调实现Android中Fragment之间的通信.pdf

    为解决 Fragment 之间的数据通信问题,提出利用接口回调实现 Fragment 之间的数据通信。 一、Fragment 的特点 Fragment 是 Android 中的一种特殊的控件,表示的是一个可以嵌入到 Activity 中的 UI 片段。它是 ...

    Java回调函数的理解

    某天,我打电话向你请教问题,当然是个难题,^_^,你一时想不出解决方法,我又不能拿着电话在那里傻等,于是我们约定:等你想出办法后打手机通知我,这样,我就挂掉电话办其它事情去了。过了XX分钟,我的手机响了,...

    策略模式结合模板方法模式

    在这种情况下,策略模式可以有三种实现方式:一是在上下文中实现公共功能,让所有具体的策略算法回调这些方法;二是把策略的接口改成抽象类,然后在里面实现具体算法的公共功能;三是给所有的策略算法定义一个抽象的...

    人人都懂设计模式 人人都懂设计模式

    在“进阶篇”中,作者讲解了设计模式在实际开发中的应用,包括过滤器模式、对象池技术、回调机制和 MVC 模式等。在“经验篇”中,作者分享了自己在设计模式和软件开发方面的经验和看法,包括设计原则、项目重构等。 ...

    Java接口回调机制

    一、前言  近在看androidFragment与Activity进行数据传递的部分,看到了接口回调的内容,来总结一下。  二、回调的含义和用途  1、什么是回调?...回调是一种双向的调用模式,也是说,被调用的接口被调

    当析构函数遇到多线程── C++ 中线程安全的对象回调

    如何避免这种竞态条件是 C++ 多线程编程面临的基本问题,可以借助 boost 的 shared_ptr 和 weak_ptr 完美解决。这也是实现线程安全的 Observer 模式的必备技术。 本文源自我在 2009 年 12 月上海 C++ 技术大会的一场...

    javascript学习指南之回调问题

    回调函数被认为是一种高级函数,一种被作为参数传递给另一个函数(在这称作"otherFunction")的高级函数,回调函数会在other...回调函数的本质是一种模式(一种解决常见问题的模式),因此回调函数也被称为回调模式。

    当析构函数遇到多线程── C++ 中线程安全的对象回调 PDF

    如何避免这种竞态条件是 C++ 多线程编程面临的基本问题,可以借助 boost 的 shared_ptr 和 weak_ptr 完美解决。这也是实现线程安全的 Observer 模式的必备技术。 本文源自陈硕在 2009 年 12 月上海 C++ 技术大会的一...

    React组件通信解决方案.docx

    在这个解决方案中,我们利用“订阅-发布模式”实现一个事件类:Event。它与 window.addEventListener 和 window.removeEventListener 类似。Event 类的实现主要包括三个方法:on、trigger 和 remove。 on 方法用于...

    转卡系统卡转卡系统支付宝转卡系统app自动回调

    本系统仅包含银行网银流水API,卡转卡模式,支持: 1. 用户账户角色管理,创建,编辑管理等; 2. 提供商户端API接口,提供查询流水到账匹配; 3. 提供商户号开通和管理功能; 5. 提供对账报表等; 6. 提供网银...

    PCM音频采集与异步播放SDK(解决阻塞问题)

    该代码为SDK,包括音频采集与播放接口,解决了音频采集直接调用wave api导致应用直接阻塞问题,采用异步线程模式,解决回调函数中调用api阻塞问题;

    异步,基于回调为Android基于Apache的Http客户端HttpClient库。.zip

    针对这些问题,用户可以尝试一些基本的解决方法,如清除应用缓存和数据、降低屏幕亮度、关闭没有使用的连接和传感器、限制后台运行的应用、删除不需要的文件和应用等。 随着Android系统的不断发展,其功能和性能也...

    RecodePlaySound.zip

    在windows系统中,使用Wave 相关API进行采集播放音频,使用线程模式代替回调模式解决设备插拔死锁问题

    nuxt.js 踩坑之旅,监听路由.docx

    本文将介绍如何使用 `watchQuery` 属性来监听路由变化,并解决在服务端渲染模式下遇到的问题。 监听路由变化 在 Nuxt.js 中,有多种方式可以监听路由变化,其中之一是使用 `watch` 属性。但是,在服务端渲染模式下...

    微前端iframe双向通信TS编译npm仓储源码

    2.发送消息时不支持消息的回调,也就是说发布订阅模式,不支持同一条消息的反向通信 综上两个问题给开发造成了很多设计及代码量上的麻烦 利用window对象提供的以上方法,我们做一下简单的封装,能很好地解决以上两...

    Android应用中使用Fragment组件的一些问题及解决方案总结

    调用show方法来显示一个Dialog(这个一个子Window,并不在Activity的视图层级中),当旋屏时,DialogFragment利用onDestroyView回调来dismiss Dialog,然后Activity重建之后,DialogFragment利用onStart回调再显示Dialog。...

    详解JavaScript异步编程中jQuery的promise对象的作用_.docx

    Promise 对象的主要作用是解决异步编程中的回调地狱问题,提供了一种简洁的方式来处理异步操作的结果。 Promise 对象的三种状态 Promise 对象有三种状态:未满足(unfulfilled)、满足(fulfilled)和失败(failed...

Global site tag (gtag.js) - Google Analytics