我通过三个故事终于学明白了三种工厂模式

时间:2022-07-22
本文章向大家介绍我通过三个故事终于学明白了三种工厂模式,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

一、简单工厂模式

介绍:

  • 1、简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪个一种实体类的实例。简单工厂模式是工厂模式家族中最简单使用的模式。
  • 2、简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为
  • 3、在软件开发中,当我们会使用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式。

大白话说:

你想要什么,告诉我,我给你就是了。

用出行的方式来举例子说明简单工厂模式。

假设人们需要出行时可以骑自行车,可以走路,可以坐公交,可以开私家车,还可以火车和飞机,当然了未来说不定还有飞船之类的。那么我们急用简单工厂模式来实现这个出行的功能:

(一)创建抽象出行类

package factory.simplefactory.goOut;
/**
 * @Auther: truedei
 * @Date: 2020 /20-4-26 22:49
 * @Description:
 */
public abstract class GoOut {
    //只是一个抽象的方法,具体的功能实现让交通工具去实现
    public abstract void run();
}

(二)创建出行方式具体实现类

(1)步行

package factory.simplefactory.goOut;

/**
 * @Auther: truedei
 * @Date: 2020 /20-4-26 22:51
 * @Description: 步行
 */
public class Walk extends GoOut{
    @Override
    public void run() {
        System.out.println("步行");
    }
}

(2)骑自行车

package factory.simplefactory.goOut;

/**
 * @Auther: truedei
 * @Date: 2020 /20-4-26 22:53
 * @Description: 骑自行车
 */
public class Bike extends GoOut{
    @Override
    public void run() {
        System.out.println("骑自行车");
    }
}

(3)开汽车

package factory.simplefactory.goOut;

/**
 * @Auther: truedei
 * @Date: 2020 /20-4-26 22:53
 * @Description:开汽车
 */
public class Car extends GoOut {
    @Override
    public void run() {
        System.out.println("开汽车");
    }
}

(三)创建工厂类

接下来创建一个工厂类,功能是提供给用户的出行的方式,用户只需要告诉工厂类他需要什么方式就好了。

package factory.simplefactory.goOut;

/**
 * @Auther: truedei
 * @Date: 2020 /20-4-26 22:58
 * @Description:为用户提供选择出行的方式。
 */
public class GoOutFactory {

    public static GoOut  createGoOut(String goOutType){
        GoOut goOut = null;

        switch (goOutType){
            case "walk":
                goOut = new Walk();
                break;
            case "bike":
                goOut = new Bike();
                break;
            case "car":
                goOut = new Car();
                break;
        }

        return goOut;
    }

}

(四)创建客户端测试

package factory.simplefactory.goOut;

/**
 * @Auther: truedei
 * @Date: 2020 /20-4-26 23:03
 * @Description:测试类
 */
public class TestGoOut {
    public static void main(String[] args) {
        GoOutFactory.createGoOut("car").run();
        GoOutFactory.createGoOut("walk").run();
        GoOutFactory.createGoOut("bike").run();
    }
}

测试结果:

开汽车
步行
骑自行车

Process finished with exit code 0

文章作者:TrueDei 作者博客首页:http://truedei.blog.csdn.net 文章原文地址:https://truedei.blog.csdn.net/article/details/105822946

二、工厂方法模式

(一)介绍

工厂方法模式:定义了一个用于创建对象的接口,让子类决定要实例化的类。工厂方法模式将一个类的实例化延迟倒子类。

(二)看一下需求,需求如下

有一个看书的程序,最初只有Python书。但是呢随着发展,也会有越来越多的书。

(三)没有使用工厂方法的代码

package factory.Product;

/**
 * @Auther: truedei
 * @Date: 2020 /20-4-28 09:02
 * @Description:
 */
public class FactoryMethod {
    public static void main(String[] args) {
        Application application = new Application();
        ProductPython ogject = application.getOgject();
        ogject.method();
    }
}

class ProductPython{
    public void method(){
        System.out.println("这是Python的产品类的方法");
    }
}

class Application{

    private ProductPython createProduct(){
        return new ProductPython();
    }

    ProductPython getOgject(){
        ProductPython product = createProduct();

        return product;
    }

}

(四)使用工厂方法模式进行重构

为了公司业务的发展需求,可以使用工厂方法模式进行代码的重构。

/**
 * @Auther: truedei
 * @Date: 2020 /20-4-28 09:02
 * @Description:
 */
public class FactoryMethod {
    public static void main(String[] args) {
        Application application = new CreateProductPython();
        Product python = application.getObject();
        python.method();

        Application application1 = new CreateProductJava();
        Product java = application1.getObject();
        java.method();
    }
}

//1、把公共的、稳定的方法给抽象出来
interface Product{
    public void method();
}


class ProductPython implements Product{

    public void method(){
        System.out.println("这是Python的产品类的方法");
    }
}

class ProductJava implements Product{

    public void method(){
        System.out.println("这是Java的产品类的方法");
    }
}

class SimpleFactory{
    public static Product createProduct(String bookType){

        if(bookType.equals("python")){
            return new ProductPython();
        }else if(bookType.equals("Java")){
            return new ProductJava();
        }else {
            return null;
        }

    }
}

abstract class Application{

    abstract Product createProduct();

    Product getObject(){
        Product product = createProduct();
        return product;
    }

}


class CreateProductPython extends Application{

    @Override
    Product createProduct() {
        return new ProductPython();
    }
}

class CreateProductJava extends Application{
    @Override
    Product createProduct() {
        return new ProductJava();
    }
}

(五)使用场景

  • 1、在不知道该使用对象的准确类型的时候
  • 2、为方便扩展组件的时候

(六)主要优点

  • 1、将具体产品和创造者解耦
  • 2、符合单一职责原则
  • 3、符合开闭原则

三、抽象工厂模式

(一)介绍

提供一个创建一系列相关或互相依赖对象的接口,而无需指定它们具体的类。

(二)实例需求说明

开发一个数据库的组件。

可以看到针对的是数据库,那么数据库又有很多种类的数据库,例如:Mysql,Oracle等。

共性:

1、连接数据

2、执行数据库命令

3、等等…

(三)实现代码

package factory.abstractFactory;

/**
 * @Auther: truedei
 * @Date: 2020 /20-4-28 18:00
 * @Description:抽象工厂模式
 */
public class AbstractFactoryTest {
    public static void main(String[] args) {
        TrueDeiDatabaseUtils tdbu = new MysqlDataBaseUtils();
        TrueDeiConnection connection = tdbu.getConnection();
        connection.connect();//连接数据库

        TrueDeiCommand command = tdbu.getCommand();
        command.command();//发送命令


        TrueDeiDatabaseUtils Otdbu = new MysqlDataBaseUtils();
        TrueDeiConnection Oconnection = Otdbu.getConnection();
        Oconnection.connect();//连接数据库

        TrueDeiCommand Ocommand = tdbu.getCommand();
        Ocommand.command();//发送命令

    }
}

//抽象连接数据库的类
interface TrueDeiConnection{
    public void connect();
}
//抽象关闭数据库连接的类
interface TrueDeiCommand{
    public void command();
}
//工具类
interface TrueDeiDatabaseUtils{
    //连接数据库
    TrueDeiConnection getConnection();

    //发送命令
    TrueDeiCommand getCommand();
}

//实现Mysql的连接实例
class MysqlConnection implements TrueDeiConnection{

    @Override
    public void connect() {
        System.out.println("连接mysql数据库");
    }
}

//实现Mysql的发送命令的实例
class MysqlCommand implements TrueDeiCommand{

    @Override
    public void command() {
        System.out.println("向mysql数据库发送命令");
    }
}


//实现Mysql的工具类  有一组接口的是工厂模式,一个接口的是工厂方法模式
class MysqlDataBaseUtils implements TrueDeiDatabaseUtils{
    @Override
    public TrueDeiConnection getConnection() {
        return new MysqlConnection();
    }

    @Override
    public TrueDeiCommand getCommand() {
        return new MysqlCommand();
    }
}



//实现Mysql的连接实例
class OracleConnection implements TrueDeiConnection{

    @Override
    public void connect() {
        System.out.println("连接Oracle数据库");
    }
}

//实现Oracle的发送命令的实例
class OracleCommand implements TrueDeiCommand{

    @Override
    public void command() {
        System.out.println("向Oracle数据库发送命令");
    }
}


//实现Oracle的工具类
class OracleDataBaseUtils implements TrueDeiDatabaseUtils{
    @Override
    public TrueDeiConnection getConnection() {
        return new OracleConnection();
    }

    @Override
    public TrueDeiCommand getCommand() {
        return new OracleCommand();
    }
}

测试结果:

连接mysql数据库
向mysql数据库发送命令
连接mysql数据库
向mysql数据库发送命令

(四)应用场景

程序需要处理不同系列的相关产品,但是您不希望它依赖于这些产品的具体类时,可以使用抽象工厂。

(五)优点

  • 1、可以确信从工厂得到的产品彼此是兼容的;
  • 2、可以避免具体产品和客户端代码之间的紧密耦合;
  • 3、符合单一职责原则;
  • 4、符合开闭原则(当新增一个功能时,不需要去修改之前的)。

(六)在源码中的应用

像连接数据库的jdbc的接口(Connection)等。