工厂模式(Factory Pattern)是一种创建对象的设计模式,它提供了一个创建对象的接口,但由子类决定要实例化的类是哪一个。这种模式对客户端隐藏了具体创建逻辑,使得代码更加灵活和可扩展。
1.简单工厂模式
java 简单工厂模式的结构图
简单工厂模式(Simple Factory Pattern)是一种创建型设计模式,它通过一个工厂类来创建对象。这种模式并不是 GoF 设计模式中的一种,但它在软件开发中非常常见。简单工厂模式适用于对象创建较为简单且数量较少的场景。
主要组成部分:
-
产品接口(Product):
- 定义了产品的接口或抽象类,所有具体产品都需要实现或继承这个接口。
-
具体产品(Concrete Product):
- 实现产品接口的具体类,定义了具体产品的特性和行为。
-
工厂类(Factory):
- 提供静态方法来创建具体产品的实例,通常通过传入参数来决定哪种产品的实例需要被创建。
优点:
-
简化对象创建:客户端只需调用工厂的静态方法,而不需要直接与具体产品类交互,简化了对象的创建过程。
-
集中管理:所有对象的创建逻辑集中在一个工厂中,方便管理和维护。
-
较易扩展:添加新产品时,只需在工厂中增加相应的创建逻辑,不需要修改现有代码(可能需要修改工厂类,但相对较少)。
缺点:
-
违反开闭原则:每次增加新产品时,都需要修改工厂类,可能导致代码的可维护性下降。
-
不支持多态性:如果产品数量过多或复杂,简单工厂模式可能会使工厂类变得庞大且难以管理。
java
// 创建业务接口
public interface IRuleConfigParser {
public void Parse(byte[] data);
}
// json实现类
class jsonRuleConfigParser implements IRuleConfigParser{
@Override
public void Parse(byte[] data) {
System.out.println("parser json rule");
}
}
// yaml实现类
class yamlRuleConfigParser implements IRuleConfigParser{
@Override
public void Parse(byte[] data) {
System.out.println("parser yaml rule");
}
}
//工厂类
class SimpleFactory{
private static final String JSON = "json";
private static final String YAML = "yaml";
public static IRuleConfigParser getInsterns(String t){
if (t.equals(JSON)){
return new jsonRuleConfigParser();
}else if (t.equals(YAML)){
return new yamlRuleConfigParser();
}
return null;
}
}
public class FactoryTest {
// 简单工厂模式测试
@Test(description = "简单工厂模式验证")
public void factoryTest(){
IRuleConfigParser json = SimpleFactory.getInsterns("json");
assert json != null;
json.Parse(new byte[]{});
IRuleConfigParser yaml = SimpleFactory.getInsterns("yaml");
assert yaml != null;
yaml.Parse(new byte[]{});
}
}
go 本身是没有构造函数的,一般而言我们采用 NewName 的方式创建对象/接口,当它返回的是接口的时候,其实就是简单工厂模式
const (
JSON = "json"
YAML = "yaml"
)
// IRuleConfigParser 定义一个接口
type IRuleConfigParser interface {
Parse(data []byte)
}
// jsonRuleConfigParser 定义一个结构体实现接口IRuleConfigParser
type jsonRuleConfigParser struct {
}
func (j jsonRuleConfigParser) Parse(data []byte) {
fmt.Println("parser json rule")
}
// yamlRuleConfigParser 定义一个结构体实现接口IRuleConfigParser
type yamlRuleConfigParser struct {
}
func (y yamlRuleConfigParser) Parse(data []byte) {
fmt.Println("parser yaml rule")
}
// NewIRuleConfigParser 创建实例对象
func NewIRuleConfigParser(t string) IRuleConfigParser {
switch t {
case JSON:
return &jsonRuleConfigParser{}
case YAML:
return &yamlRuleConfigParser{}
}
return nil
}
// TestFactory 验证简单工厂模式
func TestFactory(t *testing.T) {
type args struct {
t string
}
tests := []struct {
name string
args args
want IRuleConfigParser
}{
{
name: "json",
args: args{t: "json"},
want: jsonRuleConfigParser{},
},
{
name: "yaml",
args: args{t: "yaml"},
want: yamlRuleConfigParser{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := NewIRuleConfigParser(tt.args.t); !reflect.DeepEqual(got, tt.want) {
fmt.Printf("NewIRuleConfigParser() = %v, want %v", got, tt.want)
}
})
}
}
2.工厂方法模式
当对象的创建逻辑比较复杂,不只是简单的 new 一下就可以,而是要组合其他类对象,做各种初始化操作的时候,推荐使用工厂方法模式,将复杂的创建逻辑拆分到多个工厂类中,让每个工厂类都不至于过于复杂、
工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它通过定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法将类的实例化推迟到子类中,这样可以使得代码更加灵活和可扩展。
主要组成部分:
-
产品接口(Product):定义了产品的接口,所有具体产品都需要实现这个接口。
-
具体产品(ConcreteProduct):实现了产品接口的具体类,定义了产品的具体特性和行为。
-
工厂接口(Factory):提供一个用于创建产品对象的接口。
-
具体工厂(ConcreteFactory):实现了工厂接口,负责实例化具体产品对象。
优点:
-
可扩展性:随着新增产品,只需新增具体产品和具体工厂类,而不需要修改现有代码。
-
解耦:客户端不需要知道具体产品的类名,只需要关注产品的接口和工厂的接口,降低了代码耦合度。
-
灵活性:工厂方法允许在运行时决定实例化的产品,从而支持更灵活的架构。
使用场景:
- 当一个类无法预见它所需要的对象类型时。
- 当一个类希望由其子类来指定所创建的对象时。
- 将对象的创建和使用分离。
go
// IRuleConfigParserFactory 工厂方法接口
type IRuleConfigParserFactory interface {
CreateParser() IRuleConfigParser
}
// yamlRuleConfigParserFactory yamlRuleConfigParser 的工厂类
type yamlRuleConfigParserFactory struct {
}
func (y *yamlRuleConfigParserFactory) CreateParser() IRuleConfigParser {
return yamlRuleConfigParser{}
}
// jsonRuleConfigParserFactory jsonRuleConfigParser 的工厂类
type jsonRuleConfigParserFactory struct {
}
func (j *jsonRuleConfigParserFactory) CreateParser() IRuleConfigParser {
return jsonRuleConfigParser{}
}
// NewIRuleConfigParserFactory 用一个简单工厂封装工厂方法
func NewIRuleConfigParserFactory(t string) IRuleConfigParserFactory {
switch t {
case "json":
return &jsonRuleConfigParserFactory{}
case "yaml":
return &yamlRuleConfigParserFactory{}
}
return nil
}
func TestIRuleConfigParserFactory(t *testing.T) {
// 验证工厂方法模式
type args struct {
t string
}
tests := []struct {
name string
args args
want IRuleConfigParserFactory
}{
{
name: "json",
args: args{t: "json"},
want: &jsonRuleConfigParserFactory{},
},
{
name: "yaml",
args: args{t: "yaml"},
want: &yamlRuleConfigParserFactory{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := NewIRuleConfigParserFactory(tt.args.t); !reflect.DeepEqual(got, tt.want) {
fmt.Printf("NewIRuleConfigParserFactory() = %v, want %v", got, tt.want)
}
})
}
}
java
// 工厂接口
public interface IRuleConfigParserFactory {
IRuleConfigParser createProduct();
}
// 具体工厂json
class jsonRuleConfigParserFactory implements IRuleConfigParserFactory{
@Override
public IRuleConfigParser createProduct() {
return new jsonRuleConfigParser();
}
}
// 具体工厂yaml
class yamlRuleConfigParserFactory implements IRuleConfigParserFactory{
@Override
public IRuleConfigParser createProduct() {
return new yamlRuleConfigParser();
}
}
//工厂类
class SimpleFactory2{
private static final String JSON = "json";
private static final String YAML = "yaml";
public static IRuleConfigParser getInsterns(String t){
if (t.equals(JSON)){
return new jsonRuleConfigParserFactory().createProduct();
}else if (t.equals(YAML)){
return new yamlRuleConfigParserFactory().createProduct();
}
return null;
}
}
//工厂方法模式测试
@Test(description = "工厂方法模式验证")
public void factoryMethodTest(){
IRuleConfigParser json = SimpleFactory2.getInsterns("json");
assert json != null;
json.Parse(new byte[]{});
IRuleConfigParser yaml = SimpleFactory2.getInsterns("yaml");
assert yaml != null;
yaml.Parse(new byte[]{});
}
总结:
工厂方法模式通过提供一种创建对象的接口,从而将对象的实例化推迟到子类中,使得代码更加灵活和可扩展。它适用于对象创建较为复杂或需要应对变化的情况,是设计模式中的重要组成部分。
3.抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供了一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们具体的类。抽象工厂模式通常用于处理多个产品族的对象创建。
主要组成部分:
-
抽象产品(Abstract Product):
- 定义一系列的产品接口,通常包括多个不同类型的产品(如产品A和产品B)。
-
具体产品(Concrete Product):
- 实现了抽象产品接口的具体类,具体实现了不同产品的特性和行为。
-
抽象工厂(Abstract Factory):
- 声明创建抽象产品的方法。
-
具体工厂(Concrete Factory):
- 实现了抽象工厂接口,负责创建具体产品的实例。
优点:
-
解耦:客户端与具体产品类解耦,客户端只关注工厂的接口。
-
创建一系列相关的对象:可以创建一系列相关的产品,保持一致性。
-
可扩展性:添加新的产品族时,只需新增具体工厂,而无需修改现有代码。
使用场景:
- 当需要提供一个创建一系列相关产品的接口时。
- 当系统的产品种类是固定的,但产品的实现可能会变化时。
- 当需要在运行时动态选择产品族时。
java
// 产品接口1
public interface ProductA {
void use();
}
// 具体产品A1
class ConcreteProductA1 implements ProductA {
@Override
public void use() {
System.out.println("Using Product A1");
}
}
// 具体产品A2
class ConcreteProductA2 implements ProductA {
@Override
public void use() {
System.out.println("Using Product A2");
}
}
// 抽象产品B
interface ProductB {
void use();
}
// 具体产品B1
class ConcreteProductB1 implements ProductB {
@Override
public void use() {
System.out.println("Using Product B1");
}
}
// 具体产品B2
class ConcreteProductB2 implements ProductB {
@Override
public void use() {
System.out.println("Using Product B2");
}
}
// 抽象工厂
interface AbstractFactory {
ProductA createProductA();
ProductB createProductB();
}
// 具体工厂1
class ConcreteFactory1 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new ConcreteProductA1();
}
@Override
public ProductB createProductB() {
return new ConcreteProductB1();
}
}
// 具体工厂2
class ConcreteFactory2 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new ConcreteProductA2();
}
@Override
public ProductB createProductB() {
return new ConcreteProductB2();
}
}
go
// IRuleConfigParserA 接口
type IRuleConfigParserA interface {
Parse(data []byte)
}
// ISystemConfigParser 接口
type ISystemConfigParser interface {
ParseSystem(data []byte)
}
type jsonRuleConfigParserA struct {
}
func (j jsonRuleConfigParserA) Parse(data []byte) {
//TODO implement me
panic("implement me")
}
// jsonSystemConfigParser jsonSystemConfigParser
type jsonSystemConfigParser struct{}
// Parse Parse
func (j jsonSystemConfigParser) ParseSystem(data []byte) {
panic("implement me")
}
// IConfigParserFactory 工厂方法接口
type IConfigParserFactory interface {
CreateRuleParser() IRuleConfigParser
CreateSystemParser() ISystemConfigParser
}
type jsonConfigParserFactory struct{}
func (j jsonConfigParserFactory) CreateRuleParser() IRuleConfigParser {
return jsonRuleConfigParserA{}
}
func (j jsonConfigParserFactory) CreateSystemParser() ISystemConfigParser {
return jsonSystemConfigParser{}
}
func TestFactoryAbstract(t *testing.T) {
tests := []struct {
name string
want IRuleConfigParserA
}{
{
name: "json",
want: jsonRuleConfigParserA{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
j := jsonConfigParserFactory{}
if got := j.CreateRuleParser(); !reflect.DeepEqual(got, tt.want) {
fmt.Printf("CreateRuleParser() = %v, want %v", got, tt.want)
}
})
}
}
func TestFactoryAbstractw2(t *testing.T) {
tests := []struct {
name string
want ISystemConfigParser
}{
{
name: "sys",
want: jsonSystemConfigParser{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
j := jsonConfigParserFactory{}
if got := j.CreateSystemParser(); !reflect.DeepEqual(got, tt.want) {
fmt.Printf("CreateSystemParser() = %v, want %v", got, tt.want)
}
})
}
}