🎈 工厂模式
- 工厂模式的原理
- 作用: 就是你只要传你需要的类进去,你就能得到他的实例化对象
- 其实工厂就是帮你实例化你所需要的类
<?php
class factory
{
public static function create($className) {
return new $className();
}
}
class A {}
class B {}
$a = factory::create('A');
$b = factory::create('B');
var_dump($a);
var_dump($b);
- 工厂模式的应用
- 实例化多个类来处理不同业务时候使用,这里以求矩形和圆形的周长和面积为案例
<?php
interface shape
{
public function area();
public function perimeter();
}
class rectangle implements shape
{
private $width;
private $height;
public function __construct($width, $height) {
$this->width = $width;
$this->height = $height;
}
public function area() {
return $this->width * $this->height;
}
public function perimeter() {
return 2 * ($this->width + $this->height);
}
}
class circle implements shape
{
private $radius;
public function __construct($radius) {
$this->radius = $radius;
}
public function area() {
return M_PI * pow($this->radius, 2);
}
public function perimeter() {
return 2 * M_PI * $this->radius;
}
}
class factory
{
public static function create() {
switch (func_num_args()) {
case 1:
return new circle(func_get_arg(0));
break;
case 2:
return new rectangle(func_get_arg(0), func_get_arg(1));
break;
}
}
}
$a = factory::create(4, 5);
$b = factory::create(2);
echo '矩形的周长为:' . $a->perimeter();
echo '矩形的面积为:' . $a->area();
echo '圆的周长为:' . $a->perimeter();
echo '圆的面积为:' . $a->area();
🎈 单例模式
- 单例模式的原理
- 作用: 当你实例化多次类的时候,让其只存在在唯一的内存空间中,减少资源的消耗
- 普通类的实例化,一个
new
将会创建一个实例化内存空间,因为空间不同,这将会导致系统内存开销增大 - 但是同一个类,功能都一样,没必要放在不同的内存空间中
<?php
class A {}
$a = new A();
$b = new A();
var_dump($a);
var_dump($b);
- 单例模式的定义
- 单例模式的入门口诀是:三私一公
- 私有的构造方法: 防止人为外部使用
new
进行创建这就是上面普通内的实例化了 - 私有的克隆方法: 防止人为外部使用
clone
方法后进行实例化 - 私有的静态属性: 用来存储单一的实例化对象
- 公有的静态方法: 用来实现单一的实例化逻辑
- 从结果来看﹕两个类的对象内存空间都指向了
#1
,实现了单例模式的基础构建
<?php
class database
{
private static $instance;
private function __construct() {}
private function __clone() {}
public static function getInstance()
{
if(!self::$instance instanceof self) {
self::$instance = new self();
}
return self::$instance;
}
}
$a = database::getInstance();
$b = database::getInstance();
var_dump($a);
var_dump($b);
- 单例模式的应用
- 其实在项目中单例模式的应用很多,无非就是有些东西只需要实例化一个对象就行了,不需要多次进行实例化
- 这其中的应用场景常见的就包括
PDO
连接数据库,Redis
的连接等等
<?php
class mysql
{
private $pdo;
private static $instance;
private $_config = [
'host' => '127.0.0.1',
'post' => 3306,
'user' => 'root',
'password' => '',
'charset' => 'utf8',
'dbname' => 'autofelix',
'except' => 'PDO::ERRMODE_EXCEPTION'
];
private function __construct() {}
public function connect()
{
try {
$dsn = "mysql:host={$this->_config['host']};port={$this->_config['post']};dbname={$this->_config['dbname']};charset={$this->_config['charset']}";
$this->pdo = new PDO($dsn, $this->_config['user'], $this->_config['password']);
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, $this->_config['except']);
} catch (PDOException $e) {
exit('数据库连接失败:' . $e->getMessage());
}
}
public function getAll($sql)
{
$this->sql = $sql;
$pdostatement = $this->pdo->query($sql);
return $pdostatement->fetchAll(PDO::FETCH_ASSOC);
}
public static function getInstance()
{
if(!self::$instance instanceof self) {
self::$instance = new self();
}
return self::$instance;
}
private function __clone() {}
}
$mysql = mysql::getInstance();
$mysql->connect();
$sql = 'select * from autofelix_users where 1';
$result = $mysql->getAll($sql);
echo json_encode($result);
🎈 策略模式
- 策略模式的原理
- 作用: 比如你去淘宝上买东西,如果你是男生,它的首页会给你推荐男生喜欢的物品,如果你是女生呢,它会给你推荐女生常用的物品,策略模式其实就是给
对象进行分类
- 由上面可知,编程中的策略模式,就是会知道你是什么人,然后给你推荐你喜欢的东西,让营销最大化
- 这里必然涉及到,程序在运行的时候,给你这个人进行分门别类,然后执行了不同的方法导致的
- 这里我们定义两个类,拥有相同的方法,执行的内容却不同
- 策略模式需要做的就是当用户进来时候,同一个入口让他根据这个人的行为去执行其中某一个类中的方法
<?php
class A {
public function name()
{
echo "我是A类";
}
}
class B {
public function name()
{
echo "我是B类";
}
}
class strategy
{
private $obj;
public function getName()
{
return $this->obj->name();
}
public function setClass($class)
{
$this->obj = $class;
}
}
$strategy = new strategy();
$strategy->setClass(new B());
$strategy->getName();
- 策略模式的应用
- 情景: 一个用户去某酒店网站定住宿为例,页面上根据你的历史消费记录,会为你显示高等住宿和丰富的晚餐,或者仅仅显示大众住宿和廉价的自助餐
- 我们先定义接口去实现住房和晚餐的方法
- 然后定义两个群里的类去实现这个接口,分别是尊贵的人群和普通的人群
- 当有个
autofelix
用户去订房间,给他注入大众用户的类
<?php
interface userStrategy
{
public function hotel();
public function dinner();
}
class rich implements userStrategy
{
public function hotel()
{
return "你是高贵的客人,为你推荐了高级住宿";
}
public function dinner()
{
return "你是高贵的客人,为你推荐了烛光晚餐";
}
}
class poor implements userStrategy
{
public function hotel()
{
return "你是普通的客人,为你推荐了大众住宿";
}
public function dinner()
{
return "你是普通的客人,为你推荐了自助餐";
}
}
class user
{
private $_userClass;
public function getHotel() {
return $this->_userClass->hotel();
}
public function getDinner() {
return $this->_userClass->dinner();
}
public function setUserClass(userStrategy $userStrategy) {
$this->_userClass = $userStrategy;
}
}
class autofelix extends user {}
$people = new autofelix();
$people->setUserClass(new poor());
$hotel = $people->getHotel();
$dinner = $people->getDinner();
echo json_encode([
'hotel' => $hotel,
'dinner' => $dinner
]);
{
hotel: "你是普通的客人,为你推荐了大众住宿",
dinner: "你是普通的客人,为你推荐了自助餐"
}
🎈 适配器模式
- 适配器模式的原理
- 作用: 将一个类的接口转换成客户希望的另一个接口,适配器模式使得原本的由于接口不兼容而不能一起工作的那些类可以一起工作
- 比如:在某个场景中,老项目写了很多接口公你调用,但突然有一天,上司说要换个接口方法名调用,需要你用另一个方法名去实现相同的功能
- 你是直接改后端代码的方法名称?这肯定行不通,因为项目不止你这一个地方调用这个接口,一旦修改,其他地方就崩了,还是去重新复制那段逻辑代码,改个名字,这样不是不行,只是写了重复代码,显得臃肿了
<?php
class A
{
private $str;
public function __construct($str)
{
$this->str = $str;
}
public function getStr()
{
return $this->str;
}
public function getString()
{
return $this->str;
}
}
$a = new A('i am autofelix');
$result = $a->getStr();
var_dump($result);
- 适配器模式的应用
- 而正确的常见,应该是使用适配器模式处理这类问题
- 通过定义统一接口,然后通过实现接口去实现
<?php
class A
{
private $str;
public function __construct($str)
{
$this->str = $str;
}
public function getStr()
{
return $this->str;
}
}
interface AInterface {
function getString();
}
class B implements AInterface
{
private $_A;
public function __construct($class)
{
$this->_A = $class;
}
public function getString()
{
return $this->_A->getStr();
}
}
$a = new A('i am autofelix');
$result = $a->getStr();
var_dump($result);
$b = new B($a);
$result = $b->getString();
var_dump($result);
🎈 观察者模式
- 观察者模式的原理
- 作用: 用来监控用户的某些操作,然后根据用户这些操作来处理一些后续的事情
- 举个例子:一个用户去网上购买电影票,付款成功后,系统需要发短信给用户,顺便记录用户购票的日志等其他多个逻辑操作
<?php
interface InterfaceObserver
{
public function onListen($sender, $args);
public function getObserverName();
}
interface InterfaceObservable
{
public function addObserver($observer);
public function removeObserver($observer_name);
}
- 观察者模式的应用
- 这里以用户购票后需要给用户发送信息和记录购票日志
<?php
interface InterfaceObserver
{
public function onListen($sender, $args);
public function getObserverName();
}
interface InterfaceObservable
{
public function addObserver($observer);
public function removeObserver($observer_name);
}
class Ticket implements InterfaceObservable
{
private $_observers = [];
public function addObserver($observer)
{
if ($observer instanceof InterfaceObserver) {
$this->_observers[] = $observer;
}
}
public function removeObserver($observer_name) {}
public function buy()
{
$result = [
'code' => 200,
'msg' => '用户购票成功',
'sign' => 'ea5070bec29826cc0f8e0b7b6861fd75'
];
if($result['code'] == 200) {
foreach ($this->_observers as $observer) {
$observer->onListen($this, $result['sign']);
}
}
}
}
class ticketRecord implements InterfaceObserver
{
public function onListen($sender, $args)
{
echo "记录用户购票成功,编号为:{$args}<br/>";
}
public function getObserverName() {}
}
class sendMsg implements InterfaceObserver
{
public function onListen($sender, $args)
{
echo "您的电影票购买成功,请凭编号:{$args}观影<br/>";
}
public function getObserverName() {}
}
$ticket = new Ticket();
$ticket->addObserver(new ticketRecord());
$ticket->addObserver(new sendMsg());
$ticket->buy();