程序写着写着就会发现很多重复的代码其实是可以复用的,而且如果一开始不注意这一点越到后面越发现可复用的方法越来越多.
对比一下我第一次开发项目优化前后的代码:
public function index() { $paras = array('disease', 'type', 'level', 'price', 'district', 'rank', 'sort'); $paras = $this->_GET($paras); $start = isset($_GET['start']) ? $_GET['start'] : 0; //分页显示数 $pagesize = 6; $data['head_title'] = '体检套餐 | 袋鼠健康™'; $city_id = $this->city_id;; $package_key = 'pc_package_packages' . $city_id; $district_key = 'pc_orgs_district_key_' . $city_id; if (!$package = $this->cache->get($package_key)) { $package = CI_MyApi::excute('package/pc_get_list', array('city_id' => $city_id)); $this->cache->save($package_key, $package, CACHE_TIME); } if (!$select_item['district'] = $this->cache->get($district_key)) { $select_item['district'] = CI_MyApi::excute('district/get_entry_by_cityid', array('city_id' => $city_id), 'POST'); $this->cache->save($district_key, $select_item['district'], CACHE_TIME); } $package_class = $this->_package_class(); //套餐类型 $select_item['type'] = $package_class[2]; //高发疾病 $select_item['disease'] = $package_class[1]; //医院等级 $select_item['level'] = CI_Myenum::$hospital_level; //价格区间 $select_item['price'] = $this->_price_section(); $select_item['rank'] = $this->_rank_select(); /*$paras = [ 'level' => 2, 'district' => '1836', ];*/ $select_item = $this->_url_format($select_item, $paras); $data['package'] = $this->data_filter($paras, $package, $pagesize, $start); $data['select_item'] = $select_item; $data['nav'] = $this->_pagenav('', $data['package']['total'], $pagesize, $start); $data['location'] = $this->_get_location($paras, $select_item); $data['package_side'] = $this->get_package_by_sold($city_id); $this->render('index_tpl', $data); }
public function index() { $data['head_title'] = '体检套餐 | 袋鼠健康™'; $paras = array('disease', 'type', 'level', 'price', 'district', 'rank', 'sort'); $paras = _GET($paras); $pagesize = PACKAGE_INDEX_PAGESIZE; $start = isset($_GET['start']) ? $_GET['start'] : 0; //筛选标签 $data['select_item'] = $this->pcpackage->get_select_item($paras); //获取套餐 $data['package'] = $this->pcpackage->get_package($paras, $pagesize, $start); //分页 $data['nav'] = $this->_pagenav('', $data['package']['total'], $pagesize, $start); //侧边套餐 $data['package_side'] = $this->get_package_by_sold($this->city_id); //头部导航 $data['location'] = $this->pcpackage->get_location($paras, $data['select_item']); $this->render('index_tpl', $data); }
这里可能只能看出代码封装的问题,那么先总结封装,另外,虽然是短期内的同一个项目,但是短短几天的时间思想发生了很大的变化.所以将思想的变化以第N次开发的形式总结出来.
第一次开发,连框架的概念的很模糊,头脑里只有MVC
MVC框架中的三个模块分工都很明确,但是因为写后台而习惯了往控制器里写一大堆方法的我这次吃了一次大亏.很大一个原因是我自己没有一套思路,做到哪里写哪里.写的方法复用性很差.
这是刚开始开发第一个页面时候遇到的问题,在后半段不知为什么脑海里冒出了模块化的概念,拒绝在一个方法里写一大段代码,而是分开功能模块,于是出现了很多功能方法.
那么第一次开发的结果就是:
所有的为了完成逻辑得方法都在同一个控制器内,刚开始一个方法完成一个逻辑,一大堆代码,完全没有复用性可言.后半段开始,将逻辑拆分成功能以及逻辑模块,再组成一个完成的逻辑
偶尔出现了复用方法的情况,于是出现了一大堆功能方法.但是并没有往复用的方面考虑,写出了很多三层嵌套却又不仔细看不明所以的方法,代码高度耦合.
第二次开发
第一次开发,第二次开发是另外一个页面,很快就察觉到了一件事:
功能大同小异,但是此时思路已经完全变了,开始想着写成耦合度弱一些的方法.连回头看一下之前代码的心情都没有就直接开始写新的方法.自然也没有考虑兼容,此时还是没有往复用性的方面考虑.
第二次开发很顺利,功能模块,逻辑模块,耦合度不是那么强的方法.可以说,第二次开发只是第三次开发后半段风格的确立.写出的代码看得懂了,但是复用性很差.
第三次开发
第三次开发,是在接受了老师爸爸们的建议后的优化,对我个人来说是一种升华,一点改变就能让你的思路清晰很多
是的,第一步是封装.不要在控制器中写功能方法,通用的工具方法放到helper中,单独的逻辑模块放入library中.以及,方法的复用.
这一次耗费了我大量的时间,我重新去熟悉了CI框架的架构,知道了在MVC外要如何使用CI对象,知道了如何写自己的父类以及继承类.回头看了一下之前写的惨不忍睹的代码.
前两次开发的区别很明显,把第一次开发时写的方法删去,直接复用上第二次开发的代码,稍加修改就可以复用.于是我将通用的工具方法放入helper中,将逻辑功能放入library中.
通用的逻辑功能作为父类.从最原始的MVC变成了如下所示的扩展架构
血的领悟,真的血的领悟,控制器中,只能存放业务逻辑!!!!!!
那么在贴一些这次开发高复用的代码看看:
//代替了从数据库中操作数据,这是为了从缓存中操作数据而出现的方法.
public function data_filter($paras, $data, $pagesize, $start) { $list = $data['list']; foreach ($list as $k => $v) { //顺便加上折扣属性 嘿嘿 //$list[$k]['discount'] = $this->get_discount($v); if (isset($paras['disease']) && $paras['disease']) { if (strpos($v['package_tags'], $paras['disease'])) { unset($list[$k]); } } if (isset($paras['type']) && $paras['type']) { if ($v['package_class'] != $paras['type']) { unset($list[$k]); } } if (isset($paras['level']) && $paras['level']) { if ($v['level'] != $paras['level']) { unset($list[$k]); } } if (isset($paras['district']) && $paras['district']) { if ($v['district'] != $paras['district']) { unset($list[$k]); } } if (isset($paras['price']) && $paras['price']) { $price = explode('-', $paras['price']); $min_price = $price[0]; $max_price = $price[1]; if ($v['price'] < ($min_price * 100) || $v['price'] > ($max_price * 100)) { unset($list[$k]); } } } if (isset($paras['rank']) && $paras['rank']) { if ($paras['rank'] == 'price_asc') { $list = $this->_rank($list, 'price', SORT_ASC); } elseif ($paras['rank'] == 'price_desc') { $list = $this->_rank($list, 'price', SORT_DESC); } else { $list = $this->_rank($list, $paras['rank']); } } $total = count($list); $data['total'] = $total; $data['list'] = array_slice($list, $start, $pagesize); return $data; }
一个简单的排序方法~
/** * @param $data 需要排序的数组 * @param $param 排序的字段 * @param int $mode SORT_DESC or SORT_ASC * @return mixed */ protected function _rank($data, $param, $mode = SORT_DESC) { $flag = array(); foreach ($data as $v) { $flag[] = $v[$param]; } array_multisort($flag, $mode, $data); return $data; }