Chang Crazy's Blog

升级自己的操作系统


  • 首页

  • 归档

  • 标签

  • 分类

  • 日程表

  • 关于

  • 搜索

门面模式(singleton pattern)

2015-09-23
  • 必须拥有一个访问级别为 private 的构造函数,有效防止类被随意实例化;
  • 必须拥有一个保存类的实例的静态变量;
  • 必须拥有一个访问这个实例的公共的静态方法,该方法通常被命名为 getInstance();
  • 必须拥有一个私有的空的__clone方法,防止实例被克隆复制
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
class Singleton
{

private $name;

private static $instance;

private function __construct()
{

}

private function __clone()
{
// TODO: Implement __clone() method.
}


public static function getInstance()
{

if (!self::$instance instanceof self) {
self::$instance = new self();
}
return self::$instance;
}


public function getName()
{
return $this->name;
}

public function setName($name)
{
$this->name = $name;
}

public function sayHi()
{
echo "hi";
}

}


// 调用demo

$single = Singleton::getInstance();
//$c_single= clone $single;
$single->setName("TOM");
echo $single->getName();

门面模式(facade pattern)

2015-09-22

门面模式(Facade)或 外观模式,定义了一个高层接口,这个接口使得子系统更加容易使用:引入门面角色之后,用户只需要直接与门面角色交互,用户与子系统之间的复杂关系由门面角色来实现,从而降低了系统的耦合度。Laravel 中门面模式的使用也很广泛,基本上每个服务容器中注册的服务提供者类都对应一个门面类。(接口封装场景)

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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// OsInterface.php

namespace DesignPatterns\Structural\Facade;

/**
* OsInterface接口
*/
interface OsInterface
{
/**
* halt the OS
*/
public function halt();
}


// BiosInterface.php

namespace DesignPatterns\Structural\Facade;

/**
* BiosInterface接口
*/
interface BiosInterface
{
/**
* execute the BIOS
*/
public function execute();

/**
* wait for halt
*/
public function waitForKeyPress();

/**
* launches the OS
*
* @param OsInterface $os
*/
public function launch(OsInterface $os);

/**
* power down BIOS
*/
public function powerDown();
}


//实现

namespace DesignPatterns\Structural\Facade;

/**
* 门面类
*/
class Facade
{
/**
* @var OsInterface
*/
protected $os;

/**
* @var BiosInterface
*/
protected $bios;

/**
* This is the perfect time to use a dependency injection container
* to create an instance of this class
*
* @param BiosInterface $bios
* @param OsInterface $os
*/
public function __construct(BiosInterface $bios, OsInterface $os)
{
$this->bios = $bios;
$this->os = $os;
}

/**
* turn on the system
*/
public function turnOn()
{
$this->bios->execute();
$this->bios->waitForKeyPress();
$this->bios->launch($this->os);
}

/**
* turn off the system
*/
public function turnOff()
{
$this->os->halt();
$this->bios->powerDown();
}
}

// 测试

namespace DesignPatterns\Structural\Facade\Tests;

use DesignPatterns\Structural\Facade\Facade as Computer;
use DesignPatterns\Structural\Facade\OsInterface;

/**
* FacadeTest用于测试门面模式
*/
class FacadeTest extends \PHPUnit_Framework_TestCase
{

public function getComputer()
{
$bios = $this->getMockBuilder('DesignPatterns\Structural\Facade\BiosInterface')
->setMethods(array('launch', 'execute', 'waitForKeyPress'))
->disableAutoload()
->getMock();
$os = $this->getMockBuilder('DesignPatterns\Structural\Facade\OsInterface')
->setMethods(array('getName'))
->disableAutoload()
->getMock();
$bios->expects($this->once())
->method('launch')
->with($os);
$os->expects($this->once())
->method('getName')
->will($this->returnValue('Linux'));

$facade = new Computer($bios, $os);
return array(array($facade, $os));
}

/**
* @dataProvider getComputer
*/
public function testComputerOn(Computer $facade, OsInterface $os)
{
// interface is simpler :
$facade->turnOn();
// but I can access to lower component
$this->assertEquals('Linux', $os->getName());
}
}

观察者模式(observer pattern)

2015-09-22

观察者模式有时也被称作发布/订阅模式,该模式用于为对象实现发布/订阅功能:一旦主体对象状态发生改变,与之关联的观察者对象会收到通知,并进行相应操作。

将一个系统分割成一个一些类相互协作的类有一个不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。观察者就是解决这类的耦合关系的。

消息队列系统、事件都使用了观察者模式。

PHP 为观察者模式定义了两个接口:SplSubject 和 SplObserver。SplSubject 可以看做主体对象的抽象,SplObserver 可以看做观察者对象的抽象,要实现观察者模式,只需让主体对象实现 SplSubject ,观察者对象实现 SplObserver,并实现相应方法即可。

示例1

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
//下面两个接口,在php已经有了,直接implements即可,
interface IObserver
{
function onChanged( $sender, $args );
}

interface IObservable
{
function addObserver( $observer );
}

class UserList implements IObservable
{
private $_observers = array();

public function addCustomer( $name )
{
foreach( $this->_observers as $obs )
$obs->onChanged( $this, $name );
}

public function addObserver( $observer )
{
$this->_observers []= $observer;
}
}

class UserListLogger implements IObserver
{
public function onChanged( $sender, $args )
{
echo( "'$args' added to user list\n" );
}
}

$ul = new UserList();
$ul->addObserver( new UserListLogger());
$ul->addCustomer( "Jack" );

示例2

使用了php中的 SplSubject,SplObserver 主体对象和观察者对象类

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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178

// User.php 被观察主体对象

<?php

namespace DesignPatterns\Behavioral\Observer;

/**
* 观察者模式 : 被观察对象 (主体对象)
*
* 主体对象维护观察者列表并发送通知
*
*/
class User implements \SplSubject
{
/**
* user data
*
* @var array
*/
protected $data = array();

/**
* observers
*
* @var \SplObjectStorage
*/
protected $observers;

public function __construct()
{
$this->observers = new \SplObjectStorage();
}

/**
* 附加观察者
*
* @param \SplObserver $observer
*
* @return void
*/
public function attach(\SplObserver $observer)
{
$this->observers->attach($observer);
}

/**
* 取消观察者
*
* @param \SplObserver $observer
*
* @return void
*/
public function detach(\SplObserver $observer)
{
$this->observers->detach($observer);
}

/**
* 通知观察者方法
*
* @return void
*/
public function notify()
{
/** @var \SplObserver $observer */
foreach ($this->observers as $observer) {
$observer->update($this);
}
}

/**
*
* @param string $name
* @param mixed $value
*
* @return void
*/
public function __set($name, $value)
{
$this->data[$name] = $value;

// 通知观察者用户被改变
$this->notify();
}
}

// UserObserver.php // 观察者

namespace DesignPatterns\Behavioral\Observer;

/**
* UserObserver 类(观察者对象)
*/
class UserObserver implements \SplObserver
{
/**
* 观察者要实现的唯一方法
* 也是被 Subject 调用的方法
*
* @param \SplSubject $subject
*/
public function update(\SplSubject $subject)
{
echo get_class($subject) . ' has been updated';
}
}

// 测试

namespace DesignPatterns\Behavioral\Observer\Tests;

use DesignPatterns\Behavioral\Observer\UserObserver;
use DesignPatterns\Behavioral\Observer\User;

/**
* ObserverTest 测试观察者模式
*/
class ObserverTest extends \PHPUnit_Framework_TestCase
{

protected $observer;

protected function setUp()
{
$this->observer = new UserObserver();
}

/**
* 测试通知
*/
public function testNotify()
{
$this->expectOutputString('DesignPatterns\Behavioral\Observer\User has been updated');
$subject = new User();

$subject->attach($this->observer);
$subject->property = 123;
}

/**
* 测试订阅
*/
public function testAttachDetach()
{
$subject = new User();
$reflection = new \ReflectionProperty($subject, 'observers');

$reflection->setAccessible(true);
/** @var \SplObjectStorage $observers */
$observers = $reflection->getValue($subject);

$this->assertInstanceOf('SplObjectStorage', $observers);
$this->assertFalse($observers->contains($this->observer));

$subject->attach($this->observer);
$this->assertTrue($observers->contains($this->observer));

$subject->detach($this->observer);
$this->assertFalse($observers->contains($this->observer));
}

/**
* 测试 update() 调用
*/
public function testUpdateCalling()
{
$subject = new User();
$observer = $this->getMock('SplObserver');
$subject->attach($observer);

$observer->expects($this->once())
->method('update')
->with($subject);

$subject->notify();
}
}

官方demo

使用了SplObjectStorage 这个对象,这个对象本身有attach ,detach 的方法,如果不用,可以参考第二个

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

class MyObserver1 implements SplObserver {
public function update(SplSubject $subject) {
echo __CLASS__ . ' - ' . $subject->getName();
}
}

class MyObserver2 implements SplObserver {
public function update(SplSubject $subject) {
echo __CLASS__ . ' - ' . $subject->getName();
}
}

class MySubject implements SplSubject {
private $_observers;
private $_name;

public function __construct($name) {
$this->_observers = new SplObjectStorage();
$this->_name = $name;
}

public function attach(SplObserver $observer) {
$this->_observers->attach($observer);
}

public function detach(SplObserver $observer) {
$this->_observers->detach($observer);
}

public function notify() {
foreach ($this->_observers as $observer) {
$observer->update($this);
}
}

public function getName() {
return $this->_name;
}
}

$observer1 = new MyObserver1();
$observer2 = new MyObserver2();

$subject = new MySubject("test");

$subject->attach($observer1);
$subject->attach($observer2);
$subject->notify();

一个报纸和订阅者的例子,很像发布和订阅

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
66
67
68
69
70
71
72
73
74
75
76

/**
* Subject,that who makes news
*/
class Newspaper implements \SplSubject{
private $name;
private $observers = array();
private $content;

public function __construct($name) {
$this->name = $name;
}

//add observer
public function attach(\SplObserver $observer) {
$this->observers[] = $observer;
}

//remove observer
public function detach(\SplObserver $observer) {

$key = array_search($observer,$this->observers, true);
if($key){
unset($this->observers[$key]);
}
}

//set breakouts news
public function breakOutNews($content) {
$this->content = $content;
$this->notify();
}

public function getContent() {
return $this->content." ({$this->name})";
}

//notify observers(or some of them)
public function notify() {
foreach ($this->observers as $value) {
$value->update($this);
}
}
}

/**
* Observer,that who recieves news
*/
class Reader implements SplObserver{
private $name;

public function __construct($name) {
$this->name = $name;
}

public function update(\SplSubject $subject) {
echo $this->name.' is reading breakout news <b>'.$subject->getContent().'</b><br>';
}
}

$newspaper = new Newspaper('Newyork Times');

$allen = new Reader('Allen');
$jim = new Reader('Jim');
$linda = new Reader('Linda');

//add reader
$newspaper->attach($allen);
$newspaper->attach($jim);
$newspaper->attach($linda);

//remove reader
$newspaper->detach($linda);

//set break outs
$newspaper->breakOutNews('USA break down!');

mac 常见环境安装配置

2015-07-29

Homebrew

1
2
3
4
5
6
7
//install
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

//use
brew search /apache*/
brew install wget
brew uninstall wget

官网

阅读全文 »

成长记

2015-06-22

给你90天,成为不一样的自己

为了改变我的三分钟热度性格,我曾给自己提出一个要求,就是以”22天习惯养成”为基础。只不过,我要求自己,如果真正开始一件事就至少要坚持90天以上,而一旦坚持了90天,接下来的继续也就十分容易了。它对我的确受益匪浅,我想把它也分享给已在职场的你。如果你的确认真坚持了,I AM SURE U WILL FIND A DIFFERENT U.

阅读全文 »

批判性思维(critical thinking)

2015-06-22

批判性思维
critical thinking

怎样会来事?

2015-06-21

何为会来事?

创造双赢局面甚至创造多赢局面。那种总是能够看透那些不明显的利益取向,进而创造出来多赢的局面来。
1.即便你完全不会来事,只能独来独往,现在的这个世界也会给你一条还算不错的的路。
2.只要认真面对,在任何环境里,都能知道办法创造多赢的局面。

阅读全文 »

YC创业课笔记

2015-06-20

成为有完整作品的人

成长的最靠谱起点是什么?Sam的这篇文章里有个很好的建议:

No matter what you choose, build stuff and be around smart people. “Stuff” can be a lot of different things。 Building stuffs—-做出东西来。

我个人最看中人的这个特质。人群中只有少数人最终能拿出完整的作品—-人与人之间的差异是如此之大,乃至于少数人有作品,更少数人有好的作品,只极少数极少数人才可能作出传世的作品;而与此同时,绝大多数人(万分之九千九百九十九的人)一辈子都没有像样的作品,他们连一篇作文都写不明白。

阅读全文 »

Markdown

2015-03-15

markdown 在 sublime text 3 中使用

作为Windows/Mac/Linux下强大的文本编辑器,st提供了对Markdown语言的支持。通过设置可实现markdown预览和转换功能。而本文介绍的Markdown Preview支持Mathjax语法和目录自动生成。(Windows下),
打开st,按下组合键Control + `,出现控制台,输入

阅读全文 »

linux-aliases

2014-12-22

linux别名设置

Terminal 输入 alias 之后可以查看已经有的别名设置

如果要设置自己的别名如下:

阅读全文 »

1…567
changyuan

changyuan

不断升级自己的操作系统

69 日志
1 分类
26 标签
GitHub Twitter Weibo Zhihu
Links
  • Weibo
  • GitHub
© 2023 changyuan
载入天数... 载入时分秒...