工厂模式 是一种创建型设计模式, 其在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型。
需求的场景 这种模式在面试中经常会被问到,很多面试题的答案会表示该模式经常用于框架的db或cache组件设计。
假设你所在项目组在开发某个项目中,使用了多种缓存数据源,比如有内存,redis,本地文件。目前每次根据不同场景使用不同类型缓存,需要实例化不同缓存实例进行操作,比较繁琐。项目组开发人员希望统一调用缓存入口,简化缓存调用心智负担。
如何解决
定义cache工厂类(父类)和依赖类
编写各个类型cache子类
cache工厂类创建调用
实现
这边实现使用PHP代码作为演示,其他oop语言逻辑类似。
😼1.定义cache工厂类(父类)和依赖类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 class Config { private string $host ; private string $dbName ; private string $password ; private string $userName ; private int $port ; 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 ; } } class Cache { protected Config $config ; public function __construct (Config $config ) { $this ->config = $config ; } public static create (string $cache ) { return new $cache ($this ->config); } }
😸2.编写各个类型cache子类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 class Redis extends Cache { private Redis $redis public function __construct (Config $config ) { parent ::__construct (Config $config ); $this ->connect () } protected function connect ( ) { $this ->redis = new \Redis (); $this ->redis->connect ($this ->config->getHost () , $this ->config->getPort () ?? 6379 ); $this ->redis->auth ($this ->config->getPassword ()); } public function __call ($method , ...$arguments ) { call_user_func ([$this ->redis, $method ], ...$arguments ); } } class Memory extends Cache { public function __construct (Config $config ) { parent ::__construct (Config $config ); } } class File extends Cache { private string $cachePath = '/dev/logs/' public function __construct (Config $config ) { parent ::__construct (Config $config ); } }
😺3.cache工厂类创建调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Demo { public function run ( ) { $config = (new Config ())->setHost ('localhost' ) ->setUserName ('demo' ) ->setPassword ('*****' ); $cache = new Cache ($config ); $redis = $cache ->create (Redis ::class ); $file = $cache ->create (File ::class ); } }