还是关于设计模式

我的那个那个php程序,在实现了留言板,用户登陆,注册这些基本功能和并且对UI小做了一下设计后,就没有增加什么功能了.原因是敲代码的感觉很不舒服,添加功能也不知道去哪里加.
我在设计这个程序的一开始,就打算把所有东西纳入对象中去考虑.凭着我对类分工的浅显理解.我把显示层的东西放在Page类里,把需要与数据库的交互的操作通过Page类传给相关的类,然后返回给Page类再进行显示.但是对一些实现在类与类之间的分配总是让我犹豫很久.比如对一个字段的过滤究竟是应该放在Page类里,还是具体的操作类里,或者索性把它抽象出一个类?
一番了解后,我觉得这种犹豫可能是因为我对面向对象的一些原则理解的不够透彻,实在一点的说就是我的脑子里没有相关的设计模式.所以在这段时间阅读了很多和设计模式有关的材料.最开始买了经典的GOF的设计模式,确实这本书不是十分的易懂.后来看了网上一些评论后买了大话设计模式,一本国人写得head first式的书,觉得读起来比较容易明白-虽然有些例子实在让人起鸡皮疙瘩.再加上配合李建忠的C#设计模式纵横谈,有些时候有种醍醐灌顶的感觉.现在回过头再看GOF的书,原来莫名其妙的很多地方都会有新的理解 .
再看之前的代码,就明显感觉到粗糙.按面向对象的原则重构后,思路就会变得清晰.之后再增加逻辑,我想就比较容易了.
另外就学习设计模式的路径来说,对现有代码的重构我觉得也是一种很好的方式,至少就成就感方面来说比直接按照书上敲代码高的多.而且因为的出现才去寻找相关的模式会很有针对性.

php程序改进中

在昨天的完成登陆系统的基础上加上了注册功能,另外整套程序的架构又大改了一番,往mvc的模式上靠,依然没有使用任何框架-现在的目的并不是做出一个什么东西.其实完成基本的架构完成以后再增加功能感觉就比较简单.这也是模式的重要性.讲到编程的效率一般指两方面.一个是coding时的效率,一个是程序运行时的效率.所谓模式这东西大约就是在尽量少牺牲运行时的效率的同时大力增加coding时的效率-团队合作时更能发挥作用.
除此之外,我对一些全局性的东西该用什么存储比较头疼,网上看到了这篇文章比较有启发.虽然自己还是在用define.抽象性和效率总是一对矛盾.看来得加一个测试运行时间的东西,好在各种模式中做出取舍.
原来准备着手解决安全问题来着,可是目前广度我更加关心,在对一个完整的应用程序的各个方面有一个比较全面的了解后,考虑这些东西比较适当.
明天应该开始加上一些具体的功能了.

Project Babel分析(2)

我受不了了!本来打算可以根据程序流程来分析一个东西的源码.但是那是不可能的.对一个类的讲解势必要把另外一个类说清楚-原来以为只要说清相关的就可以了(心中的一个声音:这就和人一样….心中的另一个声音:打住!能不能先别感慨!心中的一个声音小声说:哦….#@%#@#).而如此下去网会越来越大,所以还是趁早停止为妙.还是只是以类为单位来分析比较好.尽管经验不多的人会不得要领.
写了这么点,就让他去吧.这也算一个失败的教训.
上面说了,进入主页时,$m被赋值为’home’,新建对象$p.这次我们就来研究下Page()类,所以先研究下Page()的构造函数是比较需要的.
首先判断BABEL_DEBUG是否为true(在\htdocs\core\Settings.php可以看到情况,我就不啰嗦了).不是的话关闭所有报告,否则实例化了一个Benchmark_Timer对象,接着设置开始点,在然后新建一个数组,保存调试信息.Benchmark_Timer类是Pear中的一个类,用来统计函数运行速度,具体可以参考pear手册.下面导入语言文件,新建lang()对象.连接数据库,选择数据库,设置数据库的语言.然后依然根据BABEL_DEBUG是否为真,来决定是否保存数据库的调试记录.
(预留)
下面的缓存设置用到了PEAR中的Cache_Lite类.
通过User->vxIsLogin()判断用户是否登入,检查客户端,并保存至$_SESSION['babel_ua'].删除超出规定时间的用户从表babel_online

进入了一个对$m的选择循环,进入’home’.其中首先判断在\htdocs\core\Settings.php设置的BABEL_DNS_NAME的域名是否和当前服务器运行的($_SERVER['SERVER_NAME'])一致,如果不是的话重定向到设定的域名header(’Location: http://’ . BABEL_DNS_NAME . ‘/’).首先通过$_SESSION['babel_ua']['DEVICE_LEVEL']的值判断是否是移动设备,这里为真的情况按下不表.直接进入普通情况,判断$_GET['style']值,进入Page()对象的vxHomeBundle()方法,参数,否则取在\htdocs\core\Settings.php设定的BABEL_HOME_STYLE_DEFAULT的值.在$_GET['style']设置的情况下会取$_SESSION['babel_home_style']的值.在一番判断以后同样调用vxHomeBundle()函数.打开V2EXCore.php文件看一下vxHomeBundle()的细节:

通过函数名可以大致看得出作用.不过还是看一下细节

似乎也没什么好说,设定字符集,去除客户端的缓存,加入关键字.那个if语句的作用是3秒后去某个页面,以后会用到.接下来,vxTitle函数,它可不是处理<title />这么简单啦.~
首先判断$msgSiteTitle是否为空,如果为空,则直接显示网站标题(一般为首页),否则之前加上当前页的标题.time()生成当前时间待用,把当前页的URL赋值给$_this_page待用,把几个无效页赋值给数组$_disabled_pages待用.下面就要检查当前用户是否登陆了,这里涉及到一个USER类(位于\htdocs\core\UserCore.php,还是碰到讲哪哈),判断$_SESSION['hits']的数值,这个Session就是保存当前访问的页面数,不是说一次访问多少多少页面会加钱么,就在这里控制.

Posted in php. No Comments »

Project Babel分析(1)

  1. 对地址的重定向

    在分析具体代码前需要先简单讲一下Project Babel对apache服务器的配置,本来一篇讲php项目的文章似乎与服务器端技术无关,但是在Project Babel这个项目里大量使用了apache的重定向技术,把动态的地址静态化.使用的原因我想基本有两吧:一个是基于SEO的考虑,一般搜索引擎对静态的地址比较友好,其次是防止恶意的用户直接对URL的操作.打开\apache\htaccess\.htaccess的文件可以看到下面的代码

    RewriteRule ^$ /babel.php?m=home [L]
    RewriteRule ^([0-9]+)$ /babel_mobile.php?m=home&p=$1 [L]
    RewriteRule ^index.html$ /babel.php?m=home [L]
    RewriteRule ^hot.html$ /babel.php?m=hot [L]
    RewriteRule ^home/style/shuffle.html$ /babel.php?m=home&style=shuffle [L]
    RewriteRule ^home/style/remix.html$ /babel.php?m=home&style=remix [L]
    RewriteRule ^home/style/shuffle$ /babel.php?m=home&style=shuffle [L]
    RewriteRule ^home/style/remix$ /babel.php?m=home&style=remix [L]
    RewriteRule ^home/style/remix/([a-zA-Z0-9\-]+)$ /babel.php?m=home&style=remix&go=$1 [L]
    RewriteRule ^remix/([a-zA-Z0-9\-]+)$ /babel.php?m=home&style=remix&go=$1 [L]
    (略…)

    比如这里前部分RewriteRule ^index.html$ /babel.php?m=home [L]的意思就是把index.html重定向到/babel.php?m=home.但是如果你对下面的([0-9]+)之类的东西一头雾水,那就需要补一下正则表达式的知识了.OK,知道了这点,就可以进入实际代码的分析了

  2. 基本流程

    用惯了discuz!之类的程序的朋友可能第一次打开会傻眼,为什么没有index.php文件任何程序都有入口,那Project Babel的入口是哪里呢.这里要注意的是第一Livid写的安装知道已经告诉我们要把DocumentRoot指向htdocs目录,这里是打开网页时的根目录.但是还是不见index.php啊,这里要回到重写上面说的重定向了注意到RewriteRule ^$ /babel.php?m=home [L]了么,这里就是把主页(^$间为空)重定向到了/babel.php?m=home这个网址.这里运用了get方式传递m值为home,换句话说就是在/babel.php这个文件中$_GET['m']的值为’home’.

    if (isset($_GET['m'])) {
    $m = strtolower(trim($_GET['m']));
    } else {
    $m = ‘home’;
    }

    define(’__PAGE__’, $m);

    这段代码在确定了$_GET['m']值已被定义的前提下把去掉空格的并且转换为小写赋值给$m,否则把’home’赋值给$m,然后再用其赋值常量__PAGE__.
    接下来”$p = &new Page();”,新建了一个Page()对象$p,这个对象可以说是整个Project Babel的灵魂,一般灵魂之类的东西都是比较玄乎的所以打算在讲到的时候再对其中的方法进行分析.
    总结下Project Babel的流程,就是先重定向为php可以读懂的代码,然后通过$_GET[]取出,然后通过Page类生成Page了,好了,下面很大部分应该就是Page类的分析和运用了.

Posted in php. No Comments »