设计模式代码和应用场景实例
behavioral
templete(模板方法模式)
需求:某个方法的实现需要多个步骤(类似“请客”),其中有些步骤是固定的(类似“点单”和“买单”),而有些步骤并不固定,存在可变性(类似“吃东西”)。
注意点: 钩子方法有两类:第一类钩子方法可以与一些具体步骤“挂钩”,以实现在不同条件下执行模板方法中的不同步骤,这类钩子方法的返回类型通常是bool类型的,这类方法名一般为IsXXX(),如果条件满足则执行某一步骤,否则将不执行.还有一类钩子方法就是实现体为空的具体方法,子类可以根据需要覆盖或者继承这些钩子方法
creational
structural
Adapter(适配器模式)
需求:因为老系统改造需要重写用户类,但是新的用户类接口要和原有用户类接口不兼容,需要用新类的接口封装原有的接口
注意点:旧的对象通过成员变量方式传入,这里使用组合模式(有统一的生存期,实心菱形)解耦,也可以使用继承,但是耦合度太高
<?php
class User {
private $name;
function __construct($name){
$this -> name = $name;
}
public function getName(){
return $this -> name;
}
}
interface UserInterface{
function getUserName();
}
class UserInfo Implements UserInterface {
protected $user;
function __construct($user){
$this -> user = $user;
}
public function getUserName(){
return $this -> user -> getName();
}
}
$oldUser = new User();
echo "old_user_name =".$oldUser -> getName();
$newUser = new UserInterface($oldUser);
echo "still_old_user_name =".$newUser -> getUserName();
Bridge(桥接模式)
需求:你有一个电视机的接口,还有一个遥控器的抽象类。我们都知道,将它们中任何一个定义为一个具体类都不是好办法,因为其它厂家会有不同的实现方法。
注意点:一个构件有多于一个的抽象化角色和实现化角色,系统需要它们之间进行动态耦合。在有多种可能会变化的情况下,用继承会造成类爆炸问题.
<?php
interface Workshop {
function work();
}
interface Vehicle {
protected $workshop1;
protected $workshop2;
function __construct( Workshop $workshop1 , Workshop $workshop2){
$this -> workshop1 = $workshop1;
$this -> workshop1 = $workshop2;
}
function manufacture(){
$this -> workshop1 ->work();
$this -> workshop2 ->work();
}
}
class Assemble implements Workshop{
public function work(){
echo "assembled" ;
}
}
class Produce implements Workshop{
public function work(){
echo "Produced" ;
}
}
class Car extends Vehicle{
function __construct ( Workshop $workShop1, Workshop $workShop2){
parent::__construct ( $workShop1, $workShop2);
}
public function manufacture(){
echo 'Car ';
return $this ->workshop1 ->work();
return $this ->workshop2 ->work();
}
}
class Motorcycle extends Vehicle{
function __construct ( Workshop $workShop1, Workshop $workShop2){
parent::__construct ( $workShop1, $workShop2);
}
public function manufacture(){
echo 'Motorcycle ';
return $this ->workshop1 ->work();
return $this ->workshop2 ->work();
}
}
class BridgeTest {
public function testCar(){
$vehicle = new Car(new Produce(), new Assemble());
$vehicle->manufacture();
}
public function testMotorcycle(){
$vehicle = new Motorcycle(new Produce(), new Assemble());
$vehicle->manufacture();
}
}