让我们开发的系统具有学习能力 我的突发奇想!

前言

------------------ 

刚才我在不断操作上传代码的时候,脑子闲着没事干,就在想,基本上这个上传代码的工作99%都是一样的,只是每次需要等上次上传完毕后,选择一个新的地址。这么无聊的工作,为什么不能让计算机做?

 

如果用编程去完成,是很简单,只要先输入需要上传的代码路径列表,然后一个个读取就可以了。

 

可是, 问题就是,我可能就今天2010年3月10日,才需要做一次代码上传,以后永远不需要了,为了这一次,还要专门写个系统出来,我不傻逼?

 

于是在等待+无聊点击新代码路径的过程中,我突然想到,为什么不能把整个活动抽象出来,让可变的地方我们制定,之后其他的操作依然继续?

 

正文

------------------

在以前,有过写脚本控制鼠标点游戏的外挂(起码我用过) ;在VS2005里面有貌似很强大但是又貌似很没用的宏;这些技术的本质,都是把我们的一些动作记录下来,然后交给电脑重复完成。

 

如果我抽象出来,就是一个典型的计算机模型,给定指定的输入,生成指定的输出。

也许,我不能让代码自己编写自己(实现了,我们程序员可以去抽大粪了) ;但是至少我们在已经编写好的逻辑基础上,开放一些接口,记录一些过程,然后让程序自己重复运行吧。先看个简单的例子:

 

这是个超级简单的界面,当我在输入框输入字符串,点击确认后,会在输出框输出,同时添加Hello! 后台代码是:

代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication1
{
    
public partial class Form1 : Form
    {
        
public Form1()
        {
            InitializeComponent();
        }

        
private void button_submit_Click(object sender, EventArgs e)
        {
            
string input = textBox_input.Text;

            
string output = input + ",Hello!";

            textBox_output.Text 
= output;
        }
    }
}

 

现在,这个操作需要重复100次,每次输入的内容是确定的,但是程序不知道,因此,这个就是个 输入。如果按照传统的做法,必然我们会做另外一个界面,先让用户导入各种输入,然后再做个for循环,进行操作。

 

我现在尝试用另外一种方法,思路是:

1.  有个记录系统(类似日志),记录着所有控件的变化,包括输入变化、事件变化等,然后根据时间排序。

2.  这些记录项中, 有些是可变的,例如TextBox的输入,但是大部分是不变的,例如点击button;

3.  这些记录的顺序也是不变的,例如先输入TextBox,在点击Button。 

当用户执行了一次操作后,打开记录项,然后针对可变的地方,输入各种变化值,之后就让程序根据这个运行清单执行n遍。

 

最后,就得到以下代码:

  变化后,得到:

代码
    public partial class Form1 : Form
    {
        MachineLearning learning 
= new MachineLearning();
        
public Form1()
        {
            InitializeComponent();

            textBox_input.Leave 
+= new EventHandler(machinelearning_textBox_input_Leave);
            button_submit.Click 
+= new EventHandler(machinelearning_button_submit_Click);
        }
        
void machinelearning_textBox_input_Leave(object sender, EventArgs e)
        {
            
if (learning.Repeating)
                
return;
            LearningItem item 
= new LearningItem();
            item.Type 
= ItemType.TextBox;
            item.ControlId 
= textBox_input.Name;
            item.Variable 
= textBox_input.Text;
            learning.Items.Add(item);
        }
        
void machinelearning_button_submit_Click(object sender, EventArgs e)
        {
            
if (learning.Repeating)
                
return;
            LearningItem item 
= new LearningItem();
            item.ControlId 
= button_submit.Name;
            item.Type 
= ItemType.Button;
            item.Variable 
= null;
            learning.Items.Add(item);
        }
        
private void button_submit_Click(object sender, EventArgs e)
        {
            
string input = textBox_input.Text;
            
string output = input + ",Hello!";
            textBox_output.Text 
= output;
        }
        
private void button_repeat_Click(object sender, EventArgs e)
        {
            
foreach (LearningItem item in learning.Items)
            {
                
if (item.Type == ItemType.TextBox)
                    item.Variable 
= textBox_repeat.Text;
            }
            learning.Run(
this);
        }
    }

 

 

代码
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication1
{
    
class MachineLearning
    {
        List
<LearningItem> items = new List<LearningItem>();//指令
        bool repeating = false;//是否正在重复

        
public List<LearningItem> Items { get { return items; } }
        
internal void Run(Form form)
        {
            
this.repeating = true;
            
foreach (LearningItem item in items)
            {
                Control ctrl 
= form.Controls.Find(item.ControlId, false)[0];
                
switch (item.Type)
                {
                    
case ItemType.TextBox:
                        (ctrl 
as TextBox).Text = item.Variable;
                        
break;
                    
case ItemType.Button:
                        (ctrl 
as Button).PerformClick();
                        
break;
                }
            }
            
this.repeating = false;
        }
        
public bool Repeating { get { return repeating; } }

    }
    
class LearningItem
    {
        ItemType type 
= ItemType.None;
        
string controlId;
        
string variable;
        
public ItemType Type { get { return type; } set { type = value; } }
        
public string ControlId { get { return controlId; } set { controlId = value; } }
        
public string Variable { get { return variable; } set { variable = value; } }
    }
    
public enum ItemType
    {
        None, TextBox, Button,
    }
}

 

 

现在一个没有什么用的原型系统就完成了,操作还是和刚才一样,不过操作之后,我们在重复输入框输入新的文字,然后点击重复按钮,那么系统将自动重复之前的操作。

源代码在这里下载,不过下载来也没什么用。接下来说说可行性分析。

http://www.boxcn.net/shared/r8u5yd0srd

 

可行性分析

----------------------

首先,整个理论基础是来自.net framework 框架,由于这个框架的类是有限的,因此其产生的所有业务逻辑能在有限范围内被模拟出来。通俗的说,只要我的系统是用.net写的,就一定能被机器学习并记录下来。

 

需要被记录的点一定是状态转移点,也一定是系统内部和外部交互的点。例如在TextBox输入内容、点击Button等;如果扩展下去,还包括了磁盘IO读取、http访问、socket访问、数据库访问等。

至于其他的,学习系统是不需要考虑的,这些都是业务逻辑,是死的,就像个引擎一样。

 

再次,这个学习系统是可以单独抽象成为框架,而不需要和业务逻辑结合。这个是因为微软的.net框架为我们提供了漂亮的设计模式,让对象最大程度复用,因此我们仅针对很小一部份记录就可以。例如Winform里面的Control/ EventHandler等、javascript的dom模型等。

 

性能方面,影响几乎是0. 如果采用合理的设计,可以让学习过程类似日志一样记录下来,保存在磁盘。重复的时候再加载。 

 

有什么用?实用意义?

----------------- 

这个想法主要还是来源于最近在研究测试驱动,包含了界面自动化测试;一些调试的技巧,例如Trace输出到外部系统进行捕获;进程间通讯(IPC)等。

要说有什么用嘛。也许能够实现将来操作的半自动化,再慢慢过度到全自动化。

 

比如我们在进行一系列的操作的时候,当进行了A,学习系统就会弹出下一个可能变量,我们输入后,系统再弹出下一个变量,这样复杂的操作就可以在半自动化中完成了。

 

如果要我举些有实际意义的例子,一时间还想不出来,脑子太小了。如果各位觉得没用就看看忘了,如果觉得有用,希望听听各位意见。

posted @ 2010-03-10 03:52    阅读(2549)  评论(15编辑  收藏  举报
IT民工