博客列表 >12月05日- 设计模式与依赖注入

12月05日- 设计模式与依赖注入

Eric
Eric原创
2019年12月06日 15:22:01668浏览

一、单例模式

单例模式:创建类的唯一实例

  1. class Db{
  2. // 1、静态成员私有化
  3. private static $instance = null;
  4. // 2、构造方法私有化
  5. public function __construct()
  6. {
  7. }
  8. // 3、提供一个外部访问的静态公有接口
  9. public static function getInstance(){
  10. if (self::$instance instanceof self){
  11. self::$instance = new self();
  12. }
  13. return self::$instance;
  14. }
  15. // 4、私有化克隆方法
  16. public function __clone()
  17. {
  18. }
  19. }
  20. $obj1 = Db::getInstance();
  21. $obj2 = Db::getInstance();
  22. var_dump($obj1 === $obj2); //bool(true)

使用场景:连接数据库,获取PDO实例

  1. class Db{
  2. // 1、静态成员私有化
  3. private static $pdo = null;
  4. // 2、构造方法私有化
  5. public function __construct(...$config)
  6. {
  7. list($dsn,$username,$password) = $config;
  8. try {
  9. self::$pdo = new PDO($dsn, $username, $password);
  10. } catch (Exception $e) {
  11. die('数据库连接失败:'.$e->getMessage());
  12. }
  13. }
  14. // 3、提供一个外部访问的静态公有接口
  15. public static function getInstance(...$config){
  16. if (is_null(self::$pdo)){
  17. //self::$pdo = new self(...$config); 这里表示把Db类的实例赋值给pdo对象
  18. new self(...$config);
  19. }
  20. return self::$pdo;
  21. }
  22. // 4、私有化克隆方法
  23. public function __clone()
  24. {
  25. }
  26. }
  27. $config = ['mysql:host=demo.com;dbname=demo','root','root'];
  28. $pdo = Db::getInstance(...$config);
  29. $sql = 'select * from `user`';
  30. print_r($pdo->query($sql)->fetchAll(2));

代码效果:

二、工厂模式

工厂模式:批量创建类实例/对象

  1. class Demo1
  2. {
  3. public function __construct($agr1)
  4. {
  5. echo '对象创建成功,参数是' . $agr1;
  6. }
  7. }
  8. class Demo2
  9. {
  10. public function __construct($agr1, $arg2)
  11. {
  12. echo '对象创建成功,参数是' . $agr1 .'--'. $arg2;
  13. }
  14. }
  15. class Demo3
  16. {
  17. public function __construct($agr1, $arg2, $arg3)
  18. {
  19. echo '对象创建成功,参数是' . $agr1 .'--'. $arg2 .'--'. $arg3;
  20. }
  21. }
  22. class Factory
  23. {
  24. public static function create($className, ...$args)
  25. {
  26. return new $className(...$args);
  27. }
  28. }
  29. Factory::create(Demo1::class,'100');
  30. echo '<hr>';
  31. Factory::create(Demo2::class,'100','200');
  32. echo '<hr>';
  33. Factory::create(Demo3::class,'100','200','300');

代码效果:

三、依赖注入

依赖注入:解决对象调用之间的耦合问题
实现方法:通过类的方法和构造函数以参数的形式将外部对象注入到类中

  1. class Marker{
  2. public function info(){
  3. return '苹果';
  4. }
  5. }
  6. class Product{
  7. //Marker类注入到 get()方法中
  8. public function get(Marker $marker){
  9. return 'iPhone X手机是由 '.$marker->info().' 生产的';
  10. }
  11. }
  12. class Client{
  13. //Marker类、Product类注入到 show()方法中
  14. public function show(Product $product, Marker $marker)
  15. {
  16. return $product->get($marker);
  17. }
  18. }
  19. $product = new Product();
  20. $marker = new Marker();
  21. $client = new Client();
  22. echo $client->show($product, $marker); //iPhone X手机是由 苹果 生产的

四、服务容器

服务容器:将类的 “实例” 与 “实例化” 的过程统一管理
容器实现:容器必须具有类的实例过程的绑定与执行功能

  1. class Marker{
  2. public function info(){
  3. return '苹果';
  4. }
  5. }
  6. class Product{
  7. //Marker类注入到 get()方法中
  8. public function get(Marker $marker){
  9. return 'iPhone X手机是由 '.$marker->info().' 生产的';
  10. }
  11. }
  12. class Container{
  13. //类似实例的容器
  14. protected $instance = [];
  15. //将类的实例化过程绑定到容器中
  16. public function bind($alias, Closure $closure){
  17. $this->instance[$alias] = $closure;
  18. }
  19. //将类的实例化过程从容器中取出来,执行
  20. public function make($alias, $params=[]){
  21. return call_user_func_array($this->instance[$alias], $params);
  22. }
  23. }
  24. class Client{
  25. //Marker类、Product类注入到 show()方法中
  26. public function show(Product $product, Marker $marker)
  27. {
  28. return $product->get($marker);
  29. }
  30. }
  31. $container = new Container();
  32. //将实例化过程绑定到容器中
  33. $container->bind('product', function (){return new Product();});
  34. $container->bind('marker', function (){return new Marker();});
  35. //将实例化过程取出并返回
  36. $product = $container->make('product');
  37. $marker = $container->make('marker');
  38. $client = new Client();
  39. echo $client->show($product, $marker);

五、工厂方法实例

  1. class Car{
  2. public function drive(){
  3. return '开汽车';
  4. }
  5. }
  6. class Plane{
  7. public function drive(){
  8. return '乘飞机';
  9. }
  10. }
  11. class Train{
  12. public function drive(){
  13. return '坐火车';
  14. }
  15. }
  16. //工厂模式
  17. class Factory{
  18. //类实例对象
  19. private static $instance = null;
  20. /**
  21. * 返回类的实例
  22. * @param $vehicle
  23. * @return Car|Plane|Train|null
  24. */
  25. public static function getInstance($vehicle){
  26. switch (strtolower($vehicle)){
  27. case 'car':
  28. self::$instance = new Car();
  29. break;
  30. case 'plane':
  31. self::$instance = new Plane();
  32. break;
  33. case 'train':
  34. self::$instance = new Train();
  35. break;
  36. }
  37. return self::$instance;
  38. }
  39. }
  40. class Demo{
  41. private $vehicle;
  42. //将类的实例注入到构造方法中
  43. public function __construct($vehicle)
  44. {
  45. $this->vehicle = Factory::getInstance($vehicle);
  46. }
  47. public function travel(){
  48. return $this->vehicle->drive().'---去旅行';
  49. }
  50. }
  51. $car = new Demo('car');
  52. echo $car->travel();
  53. $plane = new Demo('plane');
  54. echo $plane->travel();
  55. $train = new Demo('train');
  56. echo $train->travel();

六、面向接口编程

  1. interface iVehicle{
  2. public function drive();
  3. }
  4. class Car implements iVehicle {
  5. public function drive(){
  6. return '开汽车';
  7. }
  8. }
  9. class Plane implements iVehicle {
  10. public function drive(){
  11. return '乘飞机';
  12. }
  13. }
  14. class Train implements iVehicle {
  15. public function drive(){
  16. return '坐火车';
  17. }
  18. }
  19. class Demo{
  20. private $vehicle;
  21. //将接口注入到构造方法中
  22. public function __construct(iVehicle $vehicle)
  23. {
  24. $this->vehicle = $vehicle;
  25. }
  26. //直接使用接口的方法
  27. public function travel(){
  28. return $this->vehicle->drive().'---去旅行---接口实现';
  29. }
  30. }
  31. //Car类相当于是接口的子类
  32. $car = new Demo(new Car());
  33. echo $car->travel();
  34. //Plane类相当于是接口的子类
  35. $plane = new Demo(new Plane());
  36. echo $plane->travel();
  37. //Train类相当于是接口的子类
  38. $train = new Demo(new Train());
  39. echo $train->travel();

手写:

课堂总结:

1、单例模式创建唯一实例
2、工厂模式创建批量实例
3、依赖注入主要实现是将外部对象注入到工作类的构造函数或方法中,降低代码耦合度
4、容器统一管理类的对象和实例化过程,并在类中提供绑定方法和执行方法
5、面向接口编程:相当于把实现接口类 注入到 类中,降低耦合度

THE END !

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议