定义
工厂模式可分为三类:
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
简单工厂模式
属于创建型模式,不属于 23 种 GOF 设计模式之一,由一个工厂对象决定创建出哪一种产品类实例,逻辑为定义一个工厂类,根据传入的参数不同返回不同的产品实例,被创建的实例具有共同的父类或接口。
工厂方法模式
跟简单工厂模式的区别就是,定义了一些工厂子类,每个工厂子类都可以创建相对应的产品类实例,而不用工厂父类去根据参数创建,一般在产品类比较多的情况下,不想太多复杂的逻辑封装在工厂父类里面,可以用这种模式。
抽象工厂模式
顾名思义,把工厂抽象出来,根据具体的业务需求组合工厂创建产品实例的逻辑,通常为创建多个产品实例类。抽象工厂一旦要增加创建产品实例的逻辑,就需要修改抽象工厂接口的具体产品组合逻辑,所以并不符合开闭原则,如果是需要频繁增加(修改)产品实例的话,要衡量是否采用这种模式
基本结构
工厂模式从源码上总的来说可以分为 4 部分:
抽象产品: 通过声明接口(特性),定义了产品的业务方法。
具体产品: 通过 implement 接口(特性),定义了业务方法的具体逻辑。
抽象工厂: 按照相应的业务逻辑,声明了创建产品对象的业务方法(多数为组合方式)。
具体工厂: 通过 implement 接口(特性),定义了创建产品对象的具体逻辑。
结构设计的关键点:
- 产品只负责产品对象的创建,其他什么都不关心, 也与其他的产品不会产生任何业务逻辑上的关联
- 工厂要根据具体的业务需求去决定是否需要抽象,不要为抽象而抽象,抽象出工厂是为了更优雅的源码结构
适用场景
- 需要统一的逻辑来创建产品实例
- 各种产品实例创建逻辑很接近
- 不用关心产品实例的创建过程
- 需要有统一的入口去联动产品的创建
- 抽象工厂模式不符合开闭原则,故不适应于需要频繁增加(修改)产品的场景
如以上内容有不对之处请指导修正,谢谢。
范例代码
源码地址: https://github.com/halokid/rust-cookbook/tree/master/design_patterns/factory
trait Product {
fn convert(&self, _: String) -> String;
}
trait Factory {
fn create_product(&self) -> Box<dyn Product>;
fn convert(&self, s: String) -> String {
self.create_product().convert(s)
}
}
struct ProductX;
impl Product for ProductX {
fn convert(&self, s: String) -> String {
println!("ProductX convert: {}", s.to_uppercase());
return s.to_uppercase()
}
}
struct ProductY;
impl Product for ProductY {
fn convert(&self, s: String) -> String {
println!("ProductY convert: {}", s.to_lowercase());
return s.to_lowercase()
}
}
struct FactoryAll;
impl Factory for FactoryAll{
fn create_product(&self) -> Box<dyn Product> {
Box::new(ProductY) as Box<dyn Product>
}
}
fn main() {
let f = FactoryAll;
println!("{}", f.convert("HaloKid".to_string()))
}
来源:oschina
链接:https://my.oschina.net/halokid/blog/4953191