昨晚开始看设计模式,我决定没看一种,就把它记录下来。一是晚上看,早上到公司,边写边回味。二是决定每看一章就写一篇博客,可以监督自己不会看着看着半途而废。
这应该就是一个系列博客了,书目录总共28种设计模式。这本书是我去赶集面试时推荐给我的,推荐了2本,一本大话设计模式,一本大话数据结构。想来想去,明白了一点,语言只是工具,真正的核心在于算法,设计模式,数据结构。本系列将已PHP为代码实现
设计模式是对OOP的思维体操,本篇是设计模式之简单工厂模式。
场景:实现PHP连接Mysql。

<?php
$conn = mysql_connect('localhost', 'root', '');
mysql_select_db('blog', $conn);
?>

就这个?搞笑呢?项目里难道也用面向过程的?

<?php
class MysqlDb{
    private $conn = '';
    public function connect($host, $username, $password){
        if(empty($conn)){
            $this->conn = mysql_connect($host, $username, $password);
        }
    }

    public function selectDb($dbName){
        mysql_select_db($dbName, $this->conn);
    }
}
?>

现在,请给我加一个查询方法

<?php
class MysqlDb{
    private $conn = '';
    public function connect($host, $username, $password){
        if(empty($conn)){
            $this->conn = mysql_connect($host, $username, $password);
        }
    }

    public function selectDb($dbName){
        mysql_select_db($dbName, $this->conn);
    }

    public function query($sql){
        return mysql_query($sql);
    }
 
    public function selectOne($id){
        $sql = "SELECT * FROM `tableName` WHERE `id` = '".$id."' LIMIT 0, 1";
        return $this->query($sql);
    }

    public function selectList($id = ''){
        if(!empty($id)){
             $where = "WHERE `id` = '".$id."'";
        }
        $sql = "SELECT * FROM `tableName`".$where;
        return $this->query($sql);
    }
}
?>

好,现在项目发展了,单单Mysql不能满足需求了,请给我添加一个Redis。

<?php
class RedisDb{
    private $conn = '';
    public function connect($host, $username, $password){
        if(empty($conn)){
            $this->conn = new Redis();
            $this->conn->connect($host, $port);
            $this->conn->auth($password);
            $this->conn->select($dbName);
        }
    }
 
    public function getValue($key){
        return $this->conn->get($key);
    }

    public function setValue($key, $value){
        return $this->conn->set($key, $value);
    }
}
?>

好了,难道每次都要在代码里调用这2个类?当然不!

<?php
/**
 * 数据库工厂类 - 这就是简单工厂模式的分发。调用上面的几个类
 */
class DbFactory{
    private static $dbObj = '';
    public static function init($dbType){
        if(empty(self::$dbObj)){
            self::$dbObj = self::dbSwitch($dbType);
        }
        return $dbObj;
    }
  
    private static function dbSwitch($dbType){
        $dbType = strtolower($dbType);
        $obj = '';
        switch($dbType){
            case 'mysql':
                $obj = new MysqlDb();
                break;
            case 'redis':
                $obj = new RedisDb();
                break;
            case 'mysqli':
                $obj = new MysqliDb();
                break;
            case 'pdo':
                $obj = new PdoDb();
                break;
             default :
                exit('非法操作');
        }
        return $obj;
    }
}
?>

原文地址:http://bbs.csdn.net/topics/390729660

穷人的恶性循环:
穷 -> 需要努力工作 -> 没有时间去交际 -> 人脉越来越狭窄 -> 工作越来越难做 -> 越需要努力去工作 -> 越没有时间去发展人脉 -> 越穷

富人的良性循环:
有钱 -> 工作很轻松 -> 很多时间都在交际上 -> 人脉越来越广 -> 工作越来越不用努力 -> 越有更多的时间精力去发展人脉 -> 越富有

程序员的恶性循环:
加班 -> 没空学习 -> 老是写同等水平代码 -> 无法提升代码质量 -> 老是出BUG -> 老是需要修改 -> 加班 -> ....

想到个事情,IP5都出来的时候,我还是在用那种只能打电话接电话的直板手机,每次公司聚会的时候,老总给每个人发邮件,大家都拿出触屏的来收邮件,唯独自己一个人还是那种最老的手机 —— 三星E110C,当时自己真恨不得找个地洞钻下去,完全来错了地方一样。上司都说你每个月工资也五六K了,怎么不换个好一点的手机?穷惯了,舍不得,所受的教育一定要节俭,思想斗争,还是坚持节俭。舍不得花三四K买个好的手机。。。从小穷惯了节俭惯了,思想迂腐,只知道省钱不知道投资。

还想到一个事情,我在广州天河太古汇那上班,中午吃饭,每次都不敢进那种装修好一点的餐馆吃饭。总觉得那种地方贵吧,具体有多贵自己也说不出来也不知道,反正就是一想到就觉得贵,舍不得心疼钱。然后我每次中午要跑很远去离工作地点很远的石牌城中村吃午餐,十多二十几块钱的一份盒饭,又不卫生人有超级多,但是自己一直忍着,没办法没钱,穷命穷受罪。有一次忙一个东西实在是太远,一狠心就在上班的楼下那些餐馆吃饭吧,结果一看菜单,才发现哇靠原来这么便宜,10元一份的比比皆是,而且还有座位,环境比起城中村的那些没座位还脏兮兮的好不知道多少倍。突然之间我似乎明白出一些道理。

第三件事,我以前总是没有鞋子穿,不信可以看我以前在论坛水区发的贴,提问什么鞋子耐穿。那时候我每次都是找那种15元 25元一双的“亏本甩卖”的鞋店去买鞋,里面都是15 25一双,但是我总会挑选50、99一双的,为的是希望可以穿得久一点,不过很遗憾,每次都是最多2个月就破了报废了。然后每天都是没鞋子穿,每天都是穿着破鞋去上班,而屋里总是一大堆鞋子,但是都破了,每隔一两个月就要去这样的店铺买鞋子。后来偶然一次我算了一下,每月几乎要买一双鞋子,花费50到99,3个月就是150,还不如买一双好一点的名牌鞋子试试。但由于一直穿的鞋子不管是25 还是 50 还是99都是不到2个月就坏了,所以更是不敢去买几百一双的鞋子。恶性循环!最后一次铤而走险,花了几百块去专卖店买了一双某牌子的鞋子(这里还是隐藏牌号,免得广告)。发现居然穿了3个月都没坏掉现在还一直穿着很好。从此之后我再也不进那种25元一双的鞋店买鞋子

第四件事,我用的第一部智能手机是HTC的,G13。当时在车上、外面看到每个人用的都是HTC,认为HTC应该是非常不错的吧,ZOL手机上都拍第二了,很牛逼吧!于是花了将近2000块在国美买了一国行HTC。不过用了几个月就越来越卡,越来越慢,512M内存。一年保修期之后 刷机了,删除自带的软件了还是就只能打电话接电话了,根本算不上智能机了。之后对只能手机产生了严重的怀疑,科技这么发达,怎么一个排名第二的智能手机这么差,不说运行游戏就连QQ都运行不了了!最后想过换三星的手机,因为都是安卓的,担心又会像HTC这样,完全就只能打电话发短信。咬牙买苹果。其实我很高心自己当时能做这样的决定,用了才发现对比之下HTC根本就不能算智能手机!苹果512M内存都可以安装无数个软件应用,而 HTC G13安装了QQ QQ空间 QQ同步助手 UC浏览器 搜狗输入法就什么都装不了,且一运行就黑屏

第五件事,我在广州一家网络公司做网站程序员,月薪4K5,是我在武汉2K工资的2倍还多,心里非常哈皮,所以工作非常努力卖命。公司就我一个PHP程序员,一开始不怎么加班,但到最后我却弄得每天都加班,,,,撑了2年我最后还是累的主动辞职了,,,出来之后才发现这公司给的工资比行情低至少2K,,,,但我2年间根本从没去打探过行情,也没时间精力去打探,,,

几个故事之间似乎蕴涵着一定的道理

现在有很多的项目,对计数器的实现甚是随意,比如在实现网站文章点击数的时候,是这么设计数据表的,如:”article_id, menu_id, article_name, article_content, article_author, article_view......在article_view中记录该文章的浏览量。诈一看似乎没有问题。对于小站,比如本博客,就是这么做的,因为小菜的博客难道会涉及并发问题吗?答案显而易见,一天没多少IP,而且以后不会很大。
言归正传,对文章资讯类为主的项目,在浏览一个页面的时候不但要进行大量的查(查询上文的记录,已经所属分类的名字、热门文章资讯评论、TAG等),还要进行写操作(更新浏览数点击数)。把文章的详细内容和计数器放在一张表尽管对开发很方便,但是会造成数据库的压力过大(不然为什么大项目都要分库分表呢)。
那么,分两张表存放就好了么?一张表存文章详细信息,另一张表单独存计数器。

CREATE TABLE `article_view`(
    `article_id` int(11) NOT NULL,
    `view` int(11) NOT NULL,
    PRIMARY KEY (`article_id`)
)ENGINE=InnoDB;

这种方式,虽然分担了文章表的压力,但是每当有一个进程请求更新的时候,都会产生全局的互斥锁,只能串行,不能并行。在高并发下会有较长的等待时间。
另一种比较好的办法是对每一个文章的计数器不是一行,而是多行,比如吧,一百行。每次随机更新其中一行,该文章的浏览数就是所有行的和。

CREATE TABLE `article_view`(
    `article_id` int(11) NOT NULL,
    `pond` tinyint(4) NOT NULL COMMENT '池子,就是用来随机用的',
    `view` int(11) NOT NULL,
    PRIMARY KEY (`article_id`, `pond`)
)ENGINE=InnoDB;

小访问量的随机池子100个肯定多了,三五个足矣。每次访问的时候,随机一个数字(1-100)作为pond,如何该pond存在则更新view+1,否则插入,view=1。借助DUPLICATE KEY,不然在程序里是实现得先SELECT,判断一下再INSERT或者UPDATE。

INSERT INTO `article_view` (`article_id`, `pond`, `view`) VALUES (`123`, RAND()*100, 1) ON DUPLICATE KEY UPDATE `view`=`view`+1

获取指定文章的总访问量的时候:

SELECT SUM(`view`) FROM `article_view` WHERE `article_id`='123'

Ps:凡事都是双刃剑。为了更快的读我们通常要牺牲一些东西。在读比较多的表要加快读的速度,在写较多的表要加快写的速度。各自权衡。在加快读的速度的时候,我们牺牲的并不仅仅是写的性能,还有开发成本,开发变的更复杂,维护成本等。所以并不是读的速度越快越好,需要找一个平衡点。

注:这里仅仅是Mysql方面,有人会说高并发下你这是直接读写Mysql啦,项目的瓶颈本来就在数据库啦。。。其实。。。这里只是说Mysql的表怎么去设计而已。你完全可以在这个地方用队列去写表,你也可以把计数器在内存中保存,一直来累加,1个小时持久化一次。你也可以去用号称每秒读写十万次的Redis。

版本1.2.0改动日志:
1、前端框架BootStrap2.0升级为3.0.3。
2、布局由全屏显示变更为居中显示。
3、将评论用户提交的URL不转换为链接。
4、将错误页面统一为BootStrap布局
5、删除多个CSS和JS,提升加载速度。
6、界面美化
7、添加TAG随即显示

版本1.2.0:发布日期:2014-05-27 下载地址:https://github.com/lixuancn/LX_Blog/tree/master

版本1.0.0:发布日期:2014-03-17 下载地址:http://www.lanecn.com/themes/download/blog_1.0.0.rar

环境:PHP+Mysql

前端:bootstrap

说明:解压后是源码文件夹和数据库的MySQL文件。

数据库配置信息请在config/develop/cloud.conf.php和config/online/cloud.conf.php修改。

URL配置请在config/develop/sys.conf.php和config/online/sys.conf.php

使用请保留鄙人的友情链接。谢谢~

欢迎指正BUG。

因时间关系,做的比较粗糙。细节尚未完善。

可直接跟贴回复。每天都会看的。

问题请直接在下方留言,邮件和论坛看的不及时。留言请注明邮件。谢谢~

本文前提是安装好Virtual4.3。在Fedora下如何安装请点击http://www.lanecn.com/article/main/aid-9查看。
打开软件,点击新建。输入一个名字,随便写,自己能认就OK。按照系统默认的选项一直下一步。一直创建完成。选中创建的项目后点击上方的显示。选择一个ISO镜像文件。(XP,WIN7,老毛桃,深度,雨林木风等)。
现在虚拟机就开始开机了。
安装和正常是一样的。
本文主要说遇到如下错误:
UIDE,01-15-2008 80-MB cache,CD/DVD name is mscd001
IDE1 controller at IO address Fgooh ,chip I.D.1002438ch
IDE2 controller at IO address Fbooh ,chip I.D.10024380h
IDE2 secondary-slave disk is WDC WD 1600AAjs-22psao,ata-133
CD:IDE1 primary-master, teclast DHB16H,ATA-33.

解决方案:
1、对虚拟磁盘分区。
2、进入winPE。
3、GHOST。
4、一般下载的IOS镜像里有GHO文件。可以直接用来GHOST.
从PE安装就不会有上面的提示。