211 lines
4.1 KiB
Markdown
Raw Permalink Normal View History

2023-09-05 17:01:25 +08:00
---
title: 💫设计模式-工厂模式
2023-09-05 17:02:05 +08:00
date: 2023-09-02
2023-11-24 13:15:59 +08:00
tags:
- 设计模式
2023-09-05 17:01:25 +08:00
---
**工厂模式**是一种创建型设计模式, 其在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型。
2023-11-24 13:15:59 +08:00
## 需求的场景
2023-09-05 17:01:25 +08:00
这种模式在面试中经常会被问到很多面试题的答案会表示该模式经常用于框架的db或cache组件设计。
假设你所在项目组在开发某个项目中使用了多种缓存数据源比如有内存redis本地文件。目前每次根据不同场景使用不同类型缓存需要实例化不同缓存实例进行操作比较繁琐。项目组开发人员希望统一调用缓存入口简化缓存调用心智负担。
2023-11-24 13:15:59 +08:00
### 如何解决
2023-09-05 17:01:25 +08:00
1. 定义cache工厂类(父类)和依赖类
2. 编写各个类型cache子类
3. cache工厂类创建调用
2023-10-24 10:54:34 +08:00
<!--more-->
2023-11-24 13:15:59 +08:00
### 实现
>
2023-09-05 17:07:09 +08:00
> 这边实现使用PHP代码作为演示其他oop语言逻辑类似。
2023-09-05 17:01:25 +08:00
2023-09-05 17:07:09 +08:00
**😼1.定义cache工厂类(父类)和依赖类**
2023-09-05 17:01:25 +08:00
```php
2023-09-05 17:12:24 +08:00
// config 配置类 用于缓存实例化依赖配置数据
2023-09-05 17:01:25 +08:00
class Config
{
private string $host; //连接host
private string $dbName;// 数据库名称
private string $password;// 密码
private string $userName;// 用户名
private int $port; //端口
2023-09-05 17:01:25 +08:00
public function getHost(): string
{
return $this->host;
}
public function setHost(string $host): static
{
$this->host = $host;
return $this;
}
public function getDbName(): string
{
return $this->dbName;
}
public function setDbName(string $dbName): static
{
$this->dbName = $dbName;
return $this;
}
public function getPassword(): string
{
return $this->password;
}
public function setPassword(string $password): static
{
$this->password = $password;
return $this;
}
public function getUserName(): string
{
return $this->userName;
}
public function setUserName(string $userName): static
{
$this->userName = $userName;
return $this;
}
public function getPort(): string
{
return $this->port;
}
public function setPort(int $port): static
{
$this->port = $port;
return $this;
}
2023-09-05 17:01:25 +08:00
}
2023-09-05 17:12:24 +08:00
// 工厂类
2023-09-05 17:07:09 +08:00
2023-09-05 17:01:25 +08:00
class Cache
{
protected Config $config;
public function __construct(Config $config)
{
2023-09-05 17:12:24 +08:00
//通过构造注入Config依赖
2023-09-05 17:01:25 +08:00
$this->config = $config;
}
public static create(string $cache)
{
2023-09-05 17:12:24 +08:00
//创建实例
return new $cache($this->config);
2023-09-05 17:01:25 +08:00
}
}
2023-09-05 17:12:24 +08:00
```
**😸2.编写各个类型cache子类**
```php
// redis
2023-09-05 17:01:25 +08:00
class Redis extends Cache
{
private Redis $redis
2023-09-05 17:01:25 +08:00
public function __construct(Config $config)
{
parent::__construct(Config $config);
$this->connect()
}
protected function connect()
{
//根据Config进行缓存连接
$this->redis = new \Redis();
// 连接 Redis 服务器
$this->redis->connect($this->config->getHost() , $this->config->getPort() ?? 6379);
// 可选:设置 Redis 密码
$this->redis->auth($this->config->getPassword());
2023-09-05 17:01:25 +08:00
}
// 动态调用redis 方法
public function __call($method, ...$arguments) {
call_user_func([$this->redis, $method], ...$arguments);
}
2023-09-05 17:01:25 +08:00
}
//内存
2023-09-05 17:01:25 +08:00
class Memory extends Cache
{
public function __construct(Config $config)
{
parent::__construct(Config $config);
}
}
//文件
2023-09-05 17:01:25 +08:00
class File extends Cache
{
private string $cachePath = '/dev/logs/'
public function __construct(Config $config)
{
parent::__construct(Config $config);
}
}
```
2023-09-05 17:07:09 +08:00
**😺3.cache工厂类创建调用**
2023-09-05 17:01:25 +08:00
```php
class Demo
{
public function run()
{
$config = (new Config())->setHost('localhost')
->setUserName('demo')
->setPassword('*****');
$cache = new Cache($config);
//创建redis cache实例
$redis = $cache->create(Redis::class);
//创建本地file cache实例
$file = $cache->create(File::class);
}
}
```