PRELOADER

当前文章 : 《谈谈设计模式和代码重构》

12/17/2018 —— 

原创文章,翻版必究。如需转载请注明出处!


前言:

本文示例代码用PHP编写
本文主要是思想,代码有的是简写。


step 1 代码重构一波

现在我们如下需求:我们要将一些数据进行缓存存储到redis
话不多说,直接上代码。此示例代码可直接运行。
cache类 redis实例化为简写。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php
class cache
{
public $cacheClass;
public function __construct()
{
$this->cacheClass = 'redis:';
}

public function set($str)
{
echo $this->cacheClass.$str;
}
}

class test
{
public function a()
{
$cache = new cache();
$cache->set('a');
}

public function b()
{
$cache = new cache();
$cache->set('b');
}

public function c()
{
$cache = new cache();
$cache->set('c');
}
}

$test = new test();
$test->a();
echo "<br>";
$test->b();
echo "<br>";
$test->c();

?>

上面的代码实现了我们将方法a 、b 、 c中的字符存到了redis缓存中了。
但是我们三个地方用了 cache这个类被实例化了3次。这显然不够优雅。
当然有得童鞋会说了可以这样写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class test
{
private $cache;
public function __construct()
{
$this->cache = new cache();
}
public function a()
{
$this->cache->set('a');
}

public function b()
{
$this->cache->set('b');
}

public function c()
{
$this->cache->set('c');
}
}

因为这里都是在一个类里调用,可以写在构造方法里。
不错,这位童鞋 说明你知道如何减少不必要的重复代码。
其实这也算做是对代码的重构。
但是如果这些方法不是在一个类里呢,在多个类里呢.
这里我们就将示例代码变成如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<?php
class cache
{
public $cacheClass;
public function __construct()
{
$this->cacheClass = 'redis:';
}

public function set($str)
{
echo $this->cacheClass.$str;
}
}

class test
{
private $cache;
public function __construct()
{
$this->cache = new cache();
}
public function a()
{
$this->cache->set('a');
}
}

class test2
{
private $cache;
public function __construct()
{
$this->cache = new cache();
}
public function b()
{
$this->cache->set('b');
}
}

class test3
{
private $cache;
public function __construct()
{
$this->cache = new cache();
}
public function c()
{
$this->cache->set('c');
}
}

$test = new test();
$test->a();
echo "<br>";
$test2 = new test2();
$test2->b();
echo "<br>";
$test3 = new test3();
$test3->c();


?>


step 2 设计模式一波

设计模式:一个在程序员世界被誉为代码的最高境界。
随便一个程序员可能都会说上几种设计模式。
单例模式,观察者模式等等。。。
咦,好像发现了什么,这不是可以用单例模式吗?
心中再次默默背诵一遍,单例模式不用每次都New一个对象.
话不多说,单例模式改一波。
代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?php
class cache
{
public static function set($str)
{
$cacheClass = 'redis:';
echo $cacheClass.$str;
}
}

class test
{
public function a()
{
cache::set('a');
}
}

class test2
{
public function b()
{
cache::set('b');
}
}

class test3
{
public function c()
{
cache::set('c');
}
}

$test = new test();
$test->a();
echo "<br>";
$test2 = new test2();
$test2->b();
echo "<br>";
$test3 = new test3();
$test3->c();


?>

代码一改,不错我们用单例模式解决了new 那么多次的痛点
心里先窃喜一波,瞬间觉得自己很强大,代码写的很优雅嘛。
这时候来了一个电话,需求变了。
test2 的b 方法要用mongodb缓存。
瞬间心里一万个xxx 可是然并卵 继续撸代码.


step 3 再重构一波

消耗了一万个脑细胞 灵机一动 不就是要改test2吗?
那我可以获取cache实例的时候将类型指定啊
说干就干,代码就变成了如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<?php
class cache
{
public static function set($type,$str)
{
$cacheClass = '';
switch($type){
case 'redis':
$cacheClass = 'redis:';
break;
case 'mongodb':
$cacheClass = 'mongodb:';
break;
default:
$cacheClass = '缓存不支持';
break;
}
echo $cacheClass.$str;
}
}

class test
{
public function a()
{
cache::set('redis','a');
}
}

class test2
{
public function b()
{
cache::set('mongodb','b');
}
}

class test3
{
public function c()
{
cache::set('redis','c');
}
}

$test = new test();
$test->a();
echo "<br>";
$test2 = new test2();
$test2->b();
echo "<br>";
$test3 = new test3();
$test3->c();


?>

完美解决!心里再暗暗窃喜一波,自己怎么这么强呢!
就这样风评浪静了一年,这样的模式也用在了很多地方。


step4 再重构一波

在某一个阳光明媚的下午,睡梦中被电话吵醒!
现在test2的b方法要变成redis,test的a方法要变成mongodb 等等。。。。
很多地方的都要修改缓存的类型,
心中又是一万个xxx,这怎么办全文搜索替换。
这完全是个体力活啊,xxxxx一顿改,终于改好了。
内心确实无比的郁闷,心想这要是改一次就痛苦一次啊。
不行代码还是要重构,作为一个有追求的程序员,怎么能这样算了,忍不了。
消耗了一千万个脑细胞,总结下痛点的问题吧!这太多依赖了。
想想我能不能将这些依赖放在一个盒子里,改动以后我只要在一个地方改呢?
正向思维不行,我逆着来呢?突然脑袋中一个好的思路。
立马开始撸代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?php
class cache
{

public static function set($type,$str)
{
$cacheClass = [
'test-a' => 'mongodb',
'test2-b' => 'redis',
'test3-c' => 'mogodb'
];
$cacheClass = isset($cacheClass[$type]) ? $cacheClass[$type] : '不支持的缓存类';
echo $cacheClass.$str;
}
}

class test
{
public function a()
{
cache::set(__CLASS__.'-'.__FUNCTION__,'a');
}
}

class test2
{
public function b()
{
cache::set(__CLASS__.'-'.__FUNCTION__,'b');
}
}

class test3
{
public function c()
{
cache::set(__CLASS__.'-'.__FUNCTION__,'c');
}
}

$test = new test();
$test->a();
echo "<br>";
$test2 = new test2();
$test2->b();
echo "<br>";
$test3 = new test3();
$test3->c();


?>

代码改完,将所有的依赖反注入回去。
这样以后任他怎么改变,我只要在cache里去改他的配置就可以了。
再让我全局去改,就容易了很多。
咦,这好像是传说中的依赖注入。。。
瞬间脑海中飘出一句名言:实践是检验真理的唯一标准。
看了那么多的设计模式,也不如在代码中找到痛点并且解决痛点。
本文到这里就接近尾声了,不对按照惯例应该有一个总结才对.


总结

再完善的文档,也不能帮你写一行代码。
设计模式再好,它也是前辈们在坑里总结出来的。
不必将设计模式想的那么神,也不必按部就班。
设计模式,用好受益匪浅,用不好只会让代码晦涩难懂。
代码重构是必须的,代码没有最完美的。
但是你要对自己有一个高得要求,对自己的代码有要求。
不然你可能一直像step 3 一样一直再干苦力活。

本集终
不对忘记了,此处应该是插播广告时间啊!
编程小白想要学习编程的可以观看原创教程视频
http://lwphp.ankewk.cn/