欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 手游 > 设计模式之 工厂模式

设计模式之 工厂模式

2024/11/30 8:46:51 来源:https://blog.csdn.net/2403_82445975/article/details/143891803  浏览:    关键词:设计模式之 工厂模式

工厂模式(Factory Pattern)是一种创建对象的设计模式,属于 创建型模式(Creational Pattern)之一。其主要目的是通过定义一个工厂方法来创建对象,而不是直接通过 new 关键字实例化对象,从而将对象的创建过程与使用过程分离。这种方式能够减少代码中的耦合度,提高代码的可维护性、可扩展性,并符合面向对象设计的 单一职责原则开放封闭原则

工厂模式的核心思想是让子类决定实例化哪一个类,而父类提供创建对象的接口。它将对象的创建推迟到子类中执行。


1. 工厂模式的结构

工厂模式主要由以下几部分组成:

  1. 抽象产品(Product): 定义了产品的抽象接口,所有具体产品都会实现这个接口。

  2. 具体产品(ConcreteProduct): 实现了抽象产品接口的具体类,提供具体的实现。

  3. 抽象工厂(Creator): 定义了一个工厂方法,返回一个产品对象。此方法可以是抽象方法,也可以是具体方法,具体由子类实现。

  4. 具体工厂(ConcreteCreator): 实现了抽象工厂中的工厂方法,并返回具体的产品对象。


2. 工厂模式的分类

工厂模式可以根据工厂方法的数量和使用方式,分为以下几种类型:

  1. 简单工厂模式(Simple Factory): 又称静态工厂方法模式,它通过一个工厂类来创建对象。这个工厂类决定了具体产品的类型。简单工厂模式并不严格属于设计模式,因为它不符合开闭原则(即扩展时需要修改工厂类)。但它的实现比较简单,适用于产品类型固定的场景。

    优点

    • 客户端只依赖工厂类提供的接口,而不需要了解对象的具体类。
    • 代码可读性高,易于理解。

    缺点

    • 违反了开闭原则,如果产品需要扩展,必须修改工厂类。
    • 增加了工厂类的复杂度,尤其在产品种类较多时,工厂类会变得庞大。

    示例代码:

    // 抽象产品
    public interface Product {void doSomething();
    }// 具体产品A
    public class ProductA implements Product {@Overridepublic void doSomething() {System.out.println("Product A is doing something.");}
    }// 具体产品B
    public class ProductB implements Product {@Overridepublic void doSomething() {System.out.println("Product B is doing something.");}
    }// 工厂类
    public class SimpleFactory {public static Product createProduct(String type) {if ("A".equals(type)) {return new ProductA();} else if ("B".equals(type)) {return new ProductB();} else {return null;}}
    }// 客户端代码
    public class Client {public static void main(String[] args) {Product product = SimpleFactory.createProduct("A");product.doSomething();}
    }
    

  2. 工厂方法模式(Factory Method): 也叫做多态工厂方法,它通过定义一个抽象工厂类,允许子类去决定实例化哪一个具体产品。每个具体工厂类负责创建一个具体的产品。工厂方法模式使得扩展产品种类变得更加容易,符合 开闭原则

    优点

    • 每个工厂只负责创建一个具体的产品,符合单一职责原则。
    • 增加新产品时,只需增加新的具体产品类和具体工厂类,而无需修改现有代码。

    缺点

    • 需要为每个产品创建一个工厂类,增加了类的数量和复杂度。

    示例代码:

    // 抽象产品
    public interface Product {void doSomething();
    }// 具体产品A
    public class ProductA implements Product {@Overridepublic void doSomething() {System.out.println("Product A is doing something.");}
    }// 具体产品B
    public class ProductB implements Product {@Overridepublic void doSomething() {System.out.println("Product B is doing something.");}
    }// 抽象工厂
    public abstract class Creator {public abstract Product factoryMethod();
    }// 具体工厂A
    public class ConcreteCreatorA extends Creator {@Overridepublic Product factoryMethod() {return new ProductA();}
    }// 具体工厂B
    public class ConcreteCreatorB extends Creator {@Overridepublic Product factoryMethod() {return new ProductB();}
    }// 客户端代码
    public class Client {public static void main(String[] args) {Creator creator = new ConcreteCreatorA();Product product = creator.factoryMethod();product.doSomething();}
    }
    
  3. 抽象工厂模式(Abstract Factory): 抽象工厂模式在工厂方法模式的基础上进一步抽象,提供了一个接口,用于创建一系列相关或相互依赖的产品对象,而无需指定具体产品类。抽象工厂通常用于产品家族较大,且产品间有一定关联性的场景。

    优点

    • 可以创建一系列相关的产品对象,避免了将这些产品对象散布在各个地方。
    • 增加新的产品族时,不需要修改现有代码,符合开闭原则。

    缺点

    • 代码结构复杂,尤其是在产品家族较多时,增加了工厂类的复杂度。
    • 每新增一个产品族,就必须新增一个具体工厂类。

    示例代码:

    // 抽象产品A
    public interface ProductA {void doSomethingA();
    }// 具体产品A1
    public class ProductA1 implements ProductA {@Overridepublic void doSomethingA() {System.out.println("Product A1 is doing something.");}
    }// 具体产品A2
    public class ProductA2 implements ProductA {@Overridepublic void doSomethingA() {System.out.println("Product A2 is doing something.");}
    }// 抽象产品B
    public interface ProductB {void doSomethingB();
    }// 具体产品B1
    public class ProductB1 implements ProductB {@Overridepublic void doSomethingB() {System.out.println("Product B1 is doing something.");}
    }// 具体产品B2
    public class ProductB2 implements ProductB {@Overridepublic void doSomethingB() {System.out.println("Product B2 is doing something.");}
    }// 抽象工厂
    public interface AbstractFactory {ProductA createProductA();ProductB createProductB();
    }// 具体工厂1
    public class ConcreteFactory1 implements AbstractFactory {@Overridepublic ProductA createProductA() {return new ProductA1();}@Overridepublic ProductB createProductB() {return new ProductB1();}
    }// 具体工厂2
    public class ConcreteFactory2 implements AbstractFactory {@Overridepublic ProductA createProductA() {return new ProductA2();}@Overridepublic ProductB createProductB() {return new ProductB2();}
    }// 客户端代码
    public class Client {public static void main(String[] args) {AbstractFactory factory = new ConcreteFactory1();ProductA productA = factory.createProductA();productA.doSomethingA();ProductB productB = factory.createProductB();productB.doSomethingB();}
    }
    

3. 工厂模式+配置文件

在实际的系统设计中,工厂模式配置文件的结合使用,能够提高系统的灵活性与可扩展性,尤其是在需要根据外部配置动态创建不同对象的场景中。这种设计方式能够使得代码更加灵活、易于维护和扩展。

 工厂模式 + 配置文件的实现方式

假设我们需要根据配置来决定使用哪种数据库连接。可以使用工厂模式来封装数据库连接的创建逻辑,并通过配置类来读取外部的数据库类型配置,从而动态创建不同的数据库连接对象。

示例代码:

  • 定义产品接口(DatabaseConnection)
public interface DatabaseConnection {void connect();
}
  • 定义具体产品(MySQLConnection, PostgreSQLConnection)
public class MySQLConnection implements DatabaseConnection{@Overridepublic void connect() {System.out.println("正在连接MySQL...");}
}
public class PostgreSQLConnection implements DatabaseConnection{@Overridepublic void connect() {System.out.println("PostqreSQL正在连接中...");}
}
  • config.properties文件 
MySQL=com.study.factoryPattern.factoryAndConfigurationFile.MySQLConnection
PostgreSQL=com.study.factoryPattern.factoryAndConfigurationFile.PostgreSQLConnection
  • 工厂类(DatabaseConnectionFactory)
public class Factory {private static Map<String,DatabaseConnection> dataBaseConnections = new HashMap<>();static {//导入配置文件,并创建单例,储存在map中Properties properties = new Properties();InputStream resourceAsStream = Factory.class.getClassLoader().getResourceAsStream("config.properties");try {properties.load(resourceAsStream);Set<Object> keys = properties.keySet();for (Object key : keys) {String className = properties.getProperty((String) key);Class clazz = Class.forName(className);DatabaseConnection instance = (DatabaseConnection) clazz.newInstance();dataBaseConnections.put((String) key, instance);}} catch (Exception e) {throw new RuntimeException(e);}}public static DatabaseConnection createConnection(String name){return dataBaseConnections.get(name);}
}
  • 客户端代码
public class Client {public static void main(String[] args) {// DatabaseConnection mySQL = Factory.createConnection("MySQL");DatabaseConnection mySQL = Factory.createConnection("PostgreSQL");mySQL.connect();}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com