1、函数的深入分析

首先,我们要把函数当做一个高度复杂的生命体来看待,把它解剖一下,看看其内部的各个零件或者器官。以下面函数为例:

public class Printer
{
    public void print(String msg)
    {
        System.out.println(msg);
    }
}

其组成部分包括:

(1)函数的参数,即:String msg

(2)参数的名称,即:print

以上两部分可以包装成事件和事件类型,如下所示:

//事件类型
public enum EventType
{
    PRINT, //打印
    COPY //扫描
}

事件代码如下所示:

public class Event<T> extends EventObject implements Serializable
{
    private static final long serialVersionUID = 1L;

    private EventType eventType = EventType.PRINT;

    public Event(T param, EventType type)
    {//注意:param表示函数的参数
        super(param);
        this.eventType = type;
    }

    public EventType getEventType()
    {
        return eventType;
    }

    @SuppressWarnings("unchecked")

    public T getParam()
    {
        return (T) super.getSource();

    }
}

(3)函数的执行体,可以包装成事件处理器:

//事件处理器接口
public interface IEventHandler
{
    <T> void handleEvent(Event<T> event);
}

具体的事件处理器实现类

//具体的事件处理器实现类
public class PrintEventHandler implements IEventHandler
{

    private Printer printer = new Printer();

    public <T> void handleEvent(Event<T> event)
    {
        String param = (String) event.getParam();

        printer.print(param);
    }
}

(4)函数的调用过程:函数参数+函数执行,可以包装成事件运行器:

//事件运行器
public class EventRunner implements Runnable
{
    private final IEventHandler handler;

    private final Event<?> event;

    EventRunner(IEventHandler hand, Event<?> event)
    {
        this.handler = hand;
        this.event = event;
    }

    public void run()
    {
        handler.handleEvent(event);
    }
}

(5)函数的附着体,原先是Printer,而现在变成了事件队列:

//事件队列
public class EventQueue
{
    private static final String THREAD_PREFIX = "EventQueue";

    private boolean destroyed = false;

    private LinkedBlockingQueue<Runnable> queue;

    private ThreadPoolExecutor queueProcessor;

    public EventQueue()
    {
        queue = new LinkedBlockingQueue<Runnable>();

        queueProcessor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, queue,
                new EventThreadFactory(THREAD_PREFIX));

    }

    public void addEventRunner(EventRunner runner)
    {

        if (!destroyed)
        {
            queueProcessor.execute(runner);
        }
    }

    public void dispose()
    {
        if (!destroyed)
        {
            destroyed = true;

            queueProcessor.shutdownNow();
            queueProcessor = null;
        }
    }
}

(6)补充:线程工厂类


import java.util.concurrent.ThreadFactory;

public class EventThreadFactory implements ThreadFactory
{
    private String prefix;
    private boolean threadIsDaemon = true;
    private int threadPriority = Thread.NORM_PRIORITY;

    public EventThreadFactory(String prefix)
    {
        this(prefix, Thread.NORM_PRIORITY);
    }

    public EventThreadFactory(String prefix, int threadPriority)
    {
        this.prefix = prefix;
        this.threadPriority = threadPriority;
    }

    @Override
    public Thread newThread(Runnable runner)
    {
        Thread thread = new Thread(runner);
        String name = thread.getName();
        thread.setName(prefix + name);
        thread.setDaemon(threadIsDaemon);
        thread.setPriority(threadPriority);
        return thread;
    }
}

2.2、函数的用法对比

在未改造之前,也就是未将函数变事件改造之前,函数的用法是这样的:

public class Client
{
    public static void main(String[] args)
    {
        Printer printer = new Printer();
        printer.print("hell world!");
    }
}

而改造后,函数变成了事件,异步处理的过程是这样的:

public class ClientEvent
{
    public static void main(String[] args)
    {

        EventQueue eventQueue = new EventQueue();

        IEventHandler handler = new PrintEventHandler();

        Event<String> event = new Event<String>("hello world", EventType.PRINT);

        EventRunner runner = new EventRunner(handler, event);

        eventQueue.addEventRunner(runner);

        eventQueue.dispose();
    }
}

2.3、小作坊编码思想与工业化编码思想

虽然经过上面的改造,代码变得更繁琐了,但是获得了思想上的跃迁:从小作坊编码思想变成了工业化编程思想。

我们在工作中的代码,往往都是小作坊思想搞出来的代码,其营养价值很低。而立足于工业化思想所完成的功能开发,能让人体会编码艺术之美。

具体什么是小作坊编码思想,什么是工业化编码思想,后文将会有更多的介绍,敬请期待。