zoukankan      html  css  js  c++  java
  • [lua]再版jobSchedule与脚本描述范型

    首先贴上代码

    -- CPM:关键路径法(Critical Path Method)
    jobSchedule = {
        todos = {
            -- todo list ...
            ["finale"] = function()end;
        };
        schedule = function ( self, task, ... ) --由具体job构造任务列表 
            local finale = false
            local msg = nil
            local rc = nil
            local params = table.pack(self, task, ...)
            repeat
                local task = params[2];
                local fn = self.todos[task]
                if type(fn) == "function"
                then rc = fn(table.unpack(params, 3)) end
                finale = (task == "finale")
                msg = self.name.."["..task.."] done!"
                if not finale
                then
                    -- yield 传回进度描述及任务反馈
                    -- 打包调度入参
                    params = table.pack(coroutine.yield(msg, rc))
                end
            until finale
            self.co = nil -- over
            return msg, rc
        end;
        perform = function ( self, task, ... )
            local co = self.co or coroutine.create(self.schedule)
            if self.co == nil
            then self.co = co end
            return coroutine.resume(co, self, task, ...)
        end;
    }--jobSchedule
    ---------------------------------------------------------------
    --记得华罗庚的统筹方法论对烧水泡茶的描述过程
    --就是多任务协调的执行程序
    --示例:project, another两项任务节点的调度与描述
    --{}, 构造描述的脚本模式
    local project = {
        name = "projectSample";
        todos = {
            ["stage1"] = function()
            end;
            ["stage2"] = function()
            end;
            ["stage3"] = function()
            end;
            ["finale"] = function()end;
        };
        perform = jobSchedule.perform;
        schedule = jobSchedule.schedule;
    }
    --记得区分对象调用与域调用,一不小心就写成. 就无法识别self了
    print(project:perform("stage1"))
    --creator, object based; 基于创建对象,对象扩展的脚本模式
    function jobSchedule:Base() -- for the override method
        local meta = getmetatable(self)
        return meta and meta.__index
    end
    function jobSchedule.create( name, todos ) -- 生产工厂
        local o = {name = name, todos = todos}
        return setmetatable(o, {__index = jobSchedule})
    end
    local another = jobSchedule.create(
        "anotherProject", {
        ["stage1"] = function()
        end;
        ["stage2"] = function()
        end;
        ["finale"] = function()end;
        })
    print(another:perform("stage1"))
    print(project:perform("stage2"))
    print(project:perform("stage3"))
    local another_perform = another.perform -- back up for override it.
    function another:perform( ... ) -- example method override
        print("[override] another:perform called")
    --    return another:Base().perform(self, ...)
        return another_perform(self, ...)
    end
    print(another:perform("stage2"))
    print(project:perform("finale"))
    print(another:perform("finale"))

    描述jobSchedule模型

    上一篇已记录过jobSchedule脚本初稿;主题就是协同式多任务与并发性事务关系。

    jobSchedule就是为了描述清楚现实中关于项目计划与进度管理的一类程式化思维方法。

    现实中思维,对于工作的计划与实施的方案求解,通常认为是以下步骤:

    • 工作内容划分
      • 依赖归类
      • 时间预估
      • 优先级
    • 寻找最佳工作路径
      • 矩阵式搜索:寻求最优可行方案
      • 方案选择:制定计划

    jobSchedule脚本意义就是提倡基于这类思维方式解决问题。合理化流程制定,清晰化脚本描述。

    描述范型见解

    脚本语言往往是提供更强有力的描述性方法;能够把过程描述清楚及把范围规划清晰,问题就已经得到解决了。

    提供过程描述能力是脚本语言的主要目的,除了脚本之外的描述语言多为xml描述内容结构与依赖,json描述对象数据与结构,css……

    js融合了json描述与脚本能力;

    同样,lua也是这样一种强有力的法器;驾驭它的人可称谓脚本世界的巫师。

    通常脚本都是提供结构化描述能力和基于对象模型的组织访问,基本的function过程描述。

    脚本工作不只是构建过程,更强调内组织方式。以下主要列举三点关键

    对象构造的描述

    local project = {
        name = "projectSample";
        todos = {
            ["stage1"] = function()
            end;
            ["stage2"] = function()
            end;
            ["stage3"] = function()
            end;
            ["finale"] = function()end;
        };
        perform = jobSchedule.perform;
        schedule = jobSchedule.schedule;
    }

    最直明简洁的构造表达,就是{}赋值示意,现值构造最好如此;对象构造对外方法最好预先注释声明于其中。

    生产方式

    --creator, object based; 基于创建对象,对象扩展的脚本模式
    function jobSchedule:Base() -- for the override method
        local meta = getmetatable(self)
        return meta and meta.__index
    end
    function jobSchedule.create( name, todos ) -- 生产工厂
        local o = {name = name, todos = todos}
        return setmetatable(o, {__index = jobSchedule})
    end
    local another = jobSchedule.create(
        "anotherProject", {
        ["stage1"] = function()
        end;
        ["stage2"] = function()
        end;
        ["finale"] = function()end;
        })

    对外产生一类功能对象,最好像这样提供对外一个生产对象通过特定的方法创造新实例。实例在运行过程中,又将允许动态扩展与改造;

    对象改造

    local another_perform = another.perform -- back up for override it.
    function another:perform( ... ) -- example method override
        print("[override] another:perform called")
    --    return another:Base().perform(self, ...)
        return another_perform(self, ...)
    end

    这就说明对象功能方法的改造。这里说明了两方式改造原有方法;注释中的使用的方式依赖上文,只是为了效仿类化语言的一致化基类方法调用,并无大义。

    对象扩展:装备其他特性

    这里单独声明一个标题来强调脚本语言中对象的可塑性。

    简单扩展

    最基本的再简单不过,字段赋值表示。

    组件化扩展

    #sum.lua--

    local fn = {
    --    sum: 求和
    }
    function fn:sum( )
        local sum = 0
        local array = self
        for i=1, #array do sum = sum+array[i] end
        return sum
    end
    
    function fn.install( target )
        local meta_= getmetatable(target)
        if not meta_ then
            setmetatable(target, setmetatable({}, {__index=fn}))
        else
            meta_.__index
        end
    end
    function fn.uninstall( target )
        
    end
    return fn

    #target.lua--

    local array = {1, 2, 3, 4, 5, 6}
    require("sum").install(array)
    print(array:sum())

    --接近现实思维的操作描述。

  • 相关阅读:
    fastcgi(一)
    矩阵旋转运算(一)
    【10.9】multiprocessing多进程编程
    【10.8】多线程和多进程的比较
    【10.7】ThreadPoolExecutor线程池
    【10.6】线程同步--Semaphore 使用以及源码分析
    【10.5】线程同步--conditon 使用以及源码分析
    【10.4】线程同步--Lock、RLock
    【10.3】线程间通信--共享变量和Queue
    【10.2】多线程编程-threading
  • 原文地址:https://www.cnblogs.com/qianwen36/p/5056823.html
Copyright © 2011-2022 走看看