专栏首页猿计划我通过三个故事终于学明白了三种工厂模式

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

一、简单工厂模式

介绍:

  • 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)等。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 剑指Office-二进制中1的个数

    TrueDei
  • 终于懂了建造者模式

    TrueDei
  • 一文搞定插入排序算法

    每次处理就是将无序数列的第一个元素与有序数列的元素从后往前逐个进行比较,找出插入位置,将该元素插入到有序数列的合适位置中。

    TrueDei
  • java编程思想第四版第九章习题

    用户7798898
  • 10(01)总结形式参数,包,修饰符,内部类

    类,抽象类,接口的综合小练习 /* 教练和运动员案例(学生分析然后讲解) 乒乓球运动员和篮球运动员。 乒乓球教练和篮球教练。 为了出国交流,跟乒乓球相关...

    Java帮帮
  • 外观模式(Facade)

    qubianzhong
  • 九、委派模式与模板模式详解

    委派模式(Delegate Pattern ) 又叫委托模式, 是一种面向对象的设计模式, 允许对象组合实现与 继承相同的代码重用。它的基本作用就是负责任务的...

    编程之心
  • Java描述设计模式(12):外观模式

    知了一笑
  • 设计模式-门面模式

    cwl_java
  • 常见设计模式面试必备

    1、单例类只有一个实例对象; 2、该单例对象必须由单例类自行创建; 3、单例类对外提供一个访问该单例的全局访问点;

    挨踢小子部落阁

扫码关注云+社区

领取腾讯云代金券