GoF 23

SOLID in GoF 23

GitHub

※範囲とはClass式かObject式か

Class式:コンパイル時に静的な関連を決める(親クラスと子クラスの関係)

Object式:ラインタイム時に動的な関連を決める

对象创建型

1.原型模式;2.工厂模式;3.抽象工厂模式;4.单例模式;5.生成器

接口适配型

1.适配器模式;2.桥接模式;3.外观模式

对象去耦型

1.中介者模式;2.观察者模式

抽象集合型

1.组合模式;2.迭代器模式

行为扩展型

1.访问者模式;2.装饰器模式;3.责任链模式

算法封装型

1.模版方法模式;2.策略模式;3.命令模式

性能与对象访问型

1.享元模式;2.代理模式

对象状态型

1.备忘录模式

Iterator Pattern

PHP版

Iteratorの場合

interface IConfiguration {

function get($key);

}

abstract class Configuration implements IConfiguration, Iterator {

private $_items = array();

public function __construct() {

$this->load();

}

abstract protected function load();

protected function add($key, $value) {

$this->_items[$key] = $value;

}

public function get($key) {

return $this->_items[$key];

}

public function rewind() { reset($this->_items); }

public function current() { return current($this->_items); }

public function key() { return key($this->_items); }

public function next() { return next($this->_items); }

public function valid() { return ( $this->current() !== false ); }

}

class DBConfiguration extends Configuration {

function load() {

$this->add('myKey', 'xxx');

}

}

$c = new DBConfiguration();

echo( $c->get('myKey')."\n" );

foreach( $c as $k => $v ) {

echo( $k . " = " . $v . "\n" );

}

ArrayIteratorの場合

class Person

{

private $_name;

private $_age;

public function __construct($name, $age)

{

$this->_name = $name;

$this->_age = $age;

}

public function getAge()

{

return $this->_age;

}

}

class People implements IteratorAggregate

{

private $_people;

public function __construct()

{

$this->_people = new ArrayObject();

}

public function add(Person $person)

{

$this->_people[] = $person;

}

// Override

public function getIterator()

{

return $this->_people->getIterator();

// または

return new ArrayIterator($this->_people);

// FilterIteratorの場合

// return new AgeFilterIterator($this->_people->getIterator());

}

}

FilterIteratorの場合

class AgeFilterIterator extends FilterIterator

{

public function __construct($iterator)

{

parent::__construct($iterator);

}

// Override

public function accept()

{

$person = $this->current();

return ($person->getAge() < 20) ? true : false;

}

}

$people = new People();

$people->add(new Person('Andy', 18));

$people->add(new Person('Tom', 70));

$iterator = $people->getIterator();

foreach ($iterator as $person) {...}

// 参照位置を初期化(先頭に戻す)

$iterator->rewind();

while($iterator->valid()) {

$person = $iterator->current();

echo $person->getAge() . '\n';

$iterator->next();

}

Singleton Pattern

PHP版

class Configuration {

private $_items = array();

private static $_instance;

private function __construct() {

$this->_items['myKey'] = 'xxx';

}

private final function __clone() {}

public static function getInstance() {

if ( !isset(self::$_instance) ) {

self::$_instance = new Configuration(); // new self();

}

return self::$_instance;

}

public static function reset() {

self::$_instance = null;

}

}

$c = Configuration::getInstance();

echo( $c->{'myKey'}."\n" );

C#版(Generics)

public static class Singleton<T> where T : new()

{

private readonly static T instance = new T();

public static T Instance

{

get

{

return instance;

}

}

}

Python版

方式1

class Singleton(object):

def __new__(cls, *args, **kw):

if not hasattr(cls, '_instance'):

orig = super(Singleton, cls)

cls._instance = orig.__new__(cls, *args, **kw)

return cls._instance

class MyClass(Singleton): ...

方式2

class Singleton(object):

_state = {}

def __new__(cls, *args, **kw):

ob = super(Singleton, cls).__new__(cls, *args, **kw)

ob.__dict__ = cls._state

return ob

class MyClass(Singleton): ...

方式3

def singleton(cls, *args, **kw):

instances = {}

def getinstance():

if cls not in instances:

instances[cls] = cls(*args, **kw)

return instances[cls]

return getinstance

@singleton

class MyClass: ...

方式4

# mysingleton.py

class My_Singleton(object):

def foo(self):

pass

my_singleton = My_Singleton()

利用例

from mysingleton import my_singleton

my_singleton.foo()

Command Pattern

PHP版

interface ICommand

{

function onCommand($name, $args);

}

class CommandChain

{

private $_commands = array();

public function addCommand($cmd)

{

$this->_commands[] = $cmd;

}

public function runCommand($name, $args)

{

foreach($this->_commands as $cmd)

{

if ($cmd->onCommand($name, $args)) return;

}

}

}

class UserCommand implements ICommand

{

public function onCommand($name, $args)

{

if ($name != 'addUser') return false;

...

return true;

}

}

class MailCommand implements ICommand

{

public function onCommand($name, $args)

{

if ($name != 'sendMail') return false;

...

return true;

}

}

$cc = new CommandChain();

$cc->addCommand(new UserCommand());

$cc->addCommand(new MailCommand());

$cc->runCommand('addUser', null);

$cc->runCommand('sendMail', null);