MVC与常用设计模式
一、MVC
1.基本概念
Model(模型),程序应用功能的实现,程序的逻辑的实现。在PHP中负责数据管理,数据生成。
View(视图),图形界面逻辑。在PHP中负责输出,处理如何调用模板、需要的资源文件。
Controller(控制器),负责转发请求,对请求处理。在PHP中根据请求决定调用的视图及使用的数据。
2.为什么使用MVC
MVC的主要作用是为了将代码分层、分类。
MVC的主要目的是为了解决Web开发中分离开发与设计工作,使其工作相对独立。
在这样的过程中还发现了其他的一些优点,网站的目录结构更加清晰,网站更易维护与扩展,可以实现模块的复用。
3.模型(Model)
<?php
namespace mvc_demo;
use PDO;
//模型类
class Model
{
//获取数据
public function getData()
{
return (new PDO('mysql:host=localhost;dbname=tp5','root','wang1111'))
->query('SELECT * FROM `user` LIMIT 10')->fetchAll(PDO::FETCH_ASSOC);
}
}
//测试模型
//print_r((new Model)->getData());
4.视图(View)
<?php
namespace mvc_demo;
//视图:数据展示
class View
{
//数据展示
public function fetch($data)
{
//使用字符串拼接实现html代码
$table = '<table>';
$table .= '<caption>用户信息表</caption>';
$table .= '<tr><th>ID</th><th>用户名</th><th>账号名</th></tr>';
//遍历用户表
foreach ($data as $user){
$table .= '<tr>';
$table .= '<td>'.$user['id'].'</td>';
$table .= '<td>'.$user['name'].'</td>';
$table .= '<td>'.$user['username'].'</td>';
$table .= '</td>';
}
$table .='</table>';
return $table;
}
}
//require 'Model.php';
//echo (new View)->fetch((new Model)->getData());
5.控制器(Controller)
<?php
//控制器1
namespace mvc_demo;
//加载模型类
require 'Model.php';
//加载视图类
require 'View.php';
class Controller1
{
//获取数据,并展示出来
public function index()
{
//1.获取数据
$model = new Model();
$data = $model->getData();
//2.渲染模板
$view = new View();
return $view->fetch($data);
}
}
//客户端调用
//创建控制器实例/对象
$controller = new Controller1();
echo $controller->index();
/*
1.Model,View类的实例都是在Controller内完成的
2.控制器知道的太多,造成了当前的控制器严重依赖外部的某些对象
3.这种现象就是代码的耦合度太高
*/
6.服务容器
<?php
//控制器5:将当前依赖的外部对象,放到一个"服务容器"中进行统一管理
namespace mvc_demo;
use Closure;
//加载模型类
require 'Model.php';
//加载视图类
require 'View.php';
/*服务容器***********************************************************************************/
class Container1
{
//1.对象容器
protected $instances = [];
//2.向对象容器中添加对象
//参数1:是外部对象在当前对象容器数组中的键名/别名
//参数2:是当前需要绑定到容器的对象的实例化过程(函数)
public function bind($alias,Closure $process)
{
$this->instances[$alias] = $process;
}
//3.从对象容器中取出对象
public function make($alias,$params=[])
{
return call_user_func_array($this->instances[$alias],[]);
}
}
//将外部对象:Model,View的实例绑定到服务容器中
$container =new Container1;
//绑定模型类
$container->bind('model',function(){
return new Model();
});
//绑定到视图类
$container->bind('view',function(){
return new View();
});
/************************************************************************************/
class Controller5
{
//获取数据,并展示出来
public function index(Container1 $container)
{
//1.获取数据
$data = $container->make('model')->getData();
//2.渲染模板
return $container->make('view')->fetch($data);
}
//控制器依赖的外部对象,尽管已经通过依赖注入到了当前类中,但是没有办法实现外部对象复用
}
//客户端调用
//将外部对象的注入点从普通方法中,改到了构造方法中
$controller = new Controller5();
echo $controller->index($container);
7.Facade模式
<?php
//控制器6:Facade门面技术,静态接管服务容器中的成员的访问
namespace mvc_demo;
use Closure;
//加载模型类
require 'Model.php';
//加载视图类
require 'View.php';
/*服务容器***********************************************************************************/
class Container2
{
//1.对象容器
protected $instances = [];
//2.向对象容器中添加对象
//参数1:是外部对象在当前对象容器数组中的键名/别名
//参数2:是当前需要绑定到容器的对象的实例化过程(函数)
public function bind($alias,Closure $process)
{
$this->instances[$alias] = $process;
}
//3.从对象容器中取出对象
public function make($alias,$params=[])
{
return call_user_func_array($this->instances[$alias],[]);
}
}
//将外部对象:Model,View的实例绑定到服务容器中
$container =new Container2;
//绑定模型类
$container->bind('model',function(){
return new Model();
});
//绑定到视图类
$container->bind('view',function(){
return new View();
});
/************************************************************************************/
//在服务容器与工作的控制器之间再添加一个中间层:Facade
class Facade
{
//服务容器
protected static $container = null;
//初始化方法:给当前的Facade类和$container属性赋值
//理解为Facade的构造方法
//将外部的服务容器注入到当前的facade中
public static function initialize(Container2 $container)
{
static::$container = $container;
}
}
//模型类成员访问静态化(给成员套一个静态访问的马甲)
/************************************************************************************/
class UserModel extends Facade
{
public static function getData()
{
return static::$container->make('model')->getData();
}
}
class UserView extends Facade
{
public static function fetch($data)
{
return static::$container->make('view')->fetch($data);
}
}
/************************************************************************************/
class Controller5
{
//构造方法,初始化facade
public function __construct(Container2 $container)
{
Facade::initialize($container);
}
//用facade方式类成员
public function index()
{
//1.获取数据
$data = UserModel::getData();
//2.渲染模板
return UserView::fetch($data);
}
}
//客户端调用
//将外部对象的注入点从普通方法中,改到了构造方法中
$controller = new Controller5($container);
echo $controller->index();
学习总结
MVC就是模型(Model)、视图(View)、控制器(Controller)
模型通常是数据库的操作
视图是HTML页面
控制器主要负责调用模型与视图
服务容器,把类都放到另一个类中,可以理解为容器,然后把类都绑定到这个容器中,用的时候在取出来。
Facade模式,外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。外观模式又称为门面模式,它是一种对象结构型模式。
外观模式的就是让客户端以一种简单的方式来调用比较复杂的系统,来完成一件事情。