首先贴上代码

-- 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[];
local fn = self.todos[task]
if type(fn) == "function"
then rc = fn(table.unpack(params, )) 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 =
local array = self
for i=, #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 = {, , , , , }
require("sum").install(array)
print(array:sum())

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

[lua]再版jobSchedule与脚本描述范型的更多相关文章

  1. 利用传入的Type类型来调用范型方法的解决方案

    起因:自定义一个GridView控件,其数据源来源于一个通用方法Get<T>(),根据你传入的T到数据库中得到相应的数据,问题是定义GridView控件时没法在界面端设置使用泛型,只能在每 ...

  2. 为什么Java不允许创建范型数组

    问题示例 List<Integer>[] intListArr = new ArrayList<Integer>[8]; // 编译时报错 能看到这么看似没啥问题的一个简单语句 ...

  3. java范型集合中的成员排序

    范型集合中的类是JsonObject,不是自定义类,如果是自定义类就直接取要比较的字段值. ArrayList<JSONObject> TList = new ArrayList<J ...

  4. Java范型随笔

    最近在帝都好无聊啊, 排遣寂寞就只有让自己不要停下来,不断的思考了 QWQ; 最近做ndk, java有点忘了,突然看到了一些java范型方面的问题, 踌躇了一会, 想着想着,决定还是写个随笔记录下来 ...

  5. C# 利用范型与扩展方法重构代码

    在一些C#代码中常常可以看到 //An Simple Example By Ray Linn class CarCollection :ICollection { IList list; public ...

  6. Linux命令之dot - 绘制DOT语言脚本描述的图形

    本文链接:http://codingstandards.iteye.com/blog/840055 用途说明 Graphviz (Graph Visualization Software的缩写)是一个 ...

  7. Java Comparator的范型类型推导问题

    问题 在项目中,有一处地方需要对日期区间进行排序 我需要以日期区间的开始日为第一优先级,结束日为第二优先级进行排序 代码 我当时写的代码如下: List<Pair<LocalDate, L ...

  8. Java范型

    泛型不用考虑对象的具体类型.优点在于,因为不用考虑对象的具体类型所以可以对一类对象执行一定的相同操作:缺点在于,因为没有考虑对象的具体类型所以就不能使用对象自带的接口函数.泛型的最佳用同是实现容器类. ...

  9. Java数组协变与范型不变性

    变性是OOP语言不变的大坑,Java的数组协变就是其中的一口老坑.因为最近踩到了,便做一个记录.顺便也提一下范型的变性. 解释数组协变之前,先明确三个相关的概念,协变.不变和逆变. 一.协变.不变.逆 ...

随机推荐

  1. < < < 2013年国家集训队作业 > > >

    完成题数/总题数:  道/37道 1.  A1504. Book(王迪): 数论+贪心   ★★☆        2013中国国家集训队第二次作业 2.  A1505. 树(张闻涛): 倍增LCA+可 ...

  2. 在终端中创建一个简单的mysql表格

    打开终端后输入:/usr/local/MySQL/bin/mysql -u root –p 然后输入密码:***** 创建数据库:create database work; 使用当前数据库:use w ...

  3. Android学习(一)

    #常见布局 ###线性布局 有一个布局方向,水平或者竖直 在竖直布局下,左对齐.右对齐,水平居中生效 在水平布局下,顶部对齐.底部对齐.竖直居中生效 权重:按比例分配屏幕的剩余宽度或者高度 ###相对 ...

  4. 《Effective C++》学习笔记条款13 以对象管理资源

    条款 13 :以对象管理资源 例:      voidf()      {           Investment *pInv = createInvestment();           ... ...

  5. 在C#中如何确定一个文件是不是文本文件,以及如何确定一个文件的类型

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:在C#中如何确定一个文件是不是文本文件,以及如何确定一个文件的类型.

  6. C++的静态分发(CRTP)和动态分发(虚函数多态)的比较

    虚函数是C++实现多态的工具,在运行时根据虚表决定调用合适的函数.这被称作动态分发.虚函数很好的实现了多态的要求,但是在运行时引入了一些开销,包括: 对每一个虚函数的调用都需要额外的指针寻址 虚函数通 ...

  7. 食品药检所LIMS需求分析说明书

    1.XX市食品药检所LIMS系统需求分析... 5 1.1检验业务流程... 5 1.1.1样品受理... 5 1.1.1.1选择受理任务... 5 1.1.1.2录入检品信息... 5 1.1.1. ...

  8. ADO.NET与Oracle(一):获取多行记录集

    近期接触ADO.NET和Oracle.将我寻常遇到的一些问题和大家共享. 我认为要想入门ADO.NET操作Oracle,最主要的要求就是要会通过ADO.NET更新Oracle中的数据. 该文简单讲些利 ...

  9. 利用AWS简单存储服务(S3)托管网站

    1.首先建立Storage Bucket存储桶,名为网站域名: 2.在[属性]中选择启用网站托管或重定向到另一主机,即可. 3.官方参考文档:https://docs.aws.amazon.com/z ...

  10. VS2010 Web项目需要缺少的Web组件才能加载

    用记事本打开 .csproj 文件,找到<UseIIS>True</UseIIS>改为<UseIIS>False</UseIIS> ,重新加载项目即可.