美文网首页
工厂方法模式

工厂方法模式

作者: Tyhj | 来源:发表于2019-01-30 15:05 被阅读0次

感觉工厂方法模式,是有点难理解的;所以先讲讲使用方法,再谈谈理解

定义

定义一个用于创建对象的接口,让子类决定实例化哪个类

使用场景

在任何需要生成复杂对象的地方,都可以使用工厂方法模式

举个栗子

比如数据存储,APP一般可以将数据保存在内存、数据库、服务器这三个地方;对数据的操作,一般就是增删改查,所以我们抽象出产品类;

public interface IoHandler {
    /**
     * 保存
     */
    void save();

    /**
     * 删除
     */
    void delete();

    /**
     * 更新
     */
    void update();
}

然后具体产品类,就是实现接口保存数据到数据库

public class SqlLiteHandler implements IoHandler {
    @Override
    public void save() {
        //保存数据到数据库
    }

    @Override
    public void delete() {

    }

    @Override
    public void update() {

    }
}

就是实现接口保存数据到后台

public class ServerHandler implements IoHandler {
    @Override
    public void save() {
        //保存数据到后台
    }

    @Override
    public void delete() {

    }

    @Override
    public void update() {

    }
}

简单工厂模式

创建一个简单的工厂

public class IoFactory {
    public static IoHandler getIoHandler(String type) {
        IoHandler ioHandler = null;
        if (type.equals("server")) {
            ioHandler = new ServerHandler();
        } else if (type.equals("sqllite")) {
            ioHandler = new SqlLiteHandler();
        }
        return ioHandler;
    }
}

调用也很简单

ServerHandler handler = IoFactory.getIoHandler("server");

工厂方法模式

上面的工厂有一个问题,不符合开闭原则,新增数据保存方式的时候需要修改IoFactory,容易出错;解决方法,很简单,抽象出创建产品的接口

public interface IoFactory {
    /**
     * 创建IoHandler
     * @return
     */
    IoHandler createIoHandler();
}

实现接口,实现创建ServerHandler的工厂,创建SqlLiteHandler工厂方法也是一样

public class ServerFactory implements IoFactory {
    @Override
    public IoHandler createIoHandler() {
        return new ServerHandler();
    }
}

具体调用

ServerHandler handler = new ServerFactory().createIoHandler();

符合了开闭原则,新增一种保存方法不会影响之前的代码;每一个保存方法需要新建一个工厂,稍微有些麻烦,还有一种简洁的写法,利用反射来生产具体的对象

public interface IoFactory {
    /**
     * 创建IoHandler
     *
     * @param tClass
     * @param <T>
     * @return
     */
    <T extends IoHandler> T createIoHandler(Class<T> tClass);
}

具体的工厂类通过反射就可以获取

public class IoHandlerFactory implements IoFactory {

    @Override
    public <T extends IoHandler> T createIoHandler(Class<T> tClass) {
        IoHandler ioHandler = null;
        try {
            ioHandler = (IoHandler) Class.forName(tClass.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) ioHandler;
    }
}

具体调用

ServerHandler serverHandler=new IoHandlerFactory().createIoHandler(ServerHandler.class);
SqlLiteHandler sqlLiteHandler=new IoHandlerFactory().createIoHandler(SqlLiteHandler.class);

抽象工厂模式

其实抽象工厂模式工厂方法模式差不多,区别就是工厂方法模式一个工厂只能做一件事,比如创建一个IoHandler对象;抽象工厂模式不只是创建一个IoHandler,还得创建其他相关的对象出来;就是一个创建一组相关产品的工厂吧;实现方法和工厂方法模式一样,只是多了几种产品,抽象出来的工厂类多几个抽象方法,用来创建多的几个抽象产品,当然因为产品多了,实现的工厂类可以对产品进行组合,也更多了;

简单举个小例子

网上买电脑,CPU主板一起买会便宜不少,店铺一般也会给出几种搭配,我们选择其中一种就行了

抽象出CPU来

public interface Cpu {
    /**
     * CPU型号
     * @return
     */
    void cpuName();
}

AMD的1500X,ACpu

public class ACpu implements Cpu {
    @Override
    public void cpuName() {
        System.out.println("Ryzen 5 1500X");
    }
}

Intel的i7 9700k,ICpu

public class ICpu implements Cpu{
    @Override
    public void cpuName() {
        System.out.println("i7 9700k");
    }
}

抽象出主板来

public interface MotherBoard {
    /**
     * 主板型号
     *
     * @return
     */
    void boardName();
}

Z390主板

public class BoardZ390 implements MotherBoard{
    @Override
    public void boardName() {
        System.out.println("Z390-PLUS GAMING");
    }
}

B250主板

public class BoardB250 implements MotherBoard{
    @Override
    public void boardName() {
        System.out.println("MSI B250");
    }
}

抽象出套餐工厂

public interface ComputerFactory {

    /**
     * 组装CPU
     *
     * @return
     */
    Cpu buildCpu();

    /**
     * 组装主板
     *
     * @return
     */
    MotherBoard buildBoard();

}

Z390主板加i7CPU的高配套装

public class HighwithFactory implements ComputerFactory {
    @Override
    public Cpu buildCpu() {
        return new ICpu();
    }

    @Override
    public MotherBoard buildBoard() {
        return new BoardZ390();
    }
}

B250主板加上1500X的中配套餐

public class MediumFactory implements ComputerFactory {
    @Override
    public Cpu buildCpu() {
        return new ACpu();
    }

    @Override
    public MotherBoard buildBoard() {
        return new BoardB250();
    }
}

现在要选择高配的套餐

ComputerFactory computerFactory=new HighwithFactory();
computerFactory.buildBoard().boardName();
computerFactory.buildCpu().cpuName();

输出

Z390-PLUS GAMING
i7 9700k

但是当我把显卡、内存条、硬盘、机箱都加进来,高低配硬件也进行组合,组合就会变得很多,而套餐(工厂)就会变得非常多,就会创建非常多的类,因此开发中需要谨慎使用

工厂方法的理解

需要抽象出产品,抽象出工厂,实现不同的工厂去创建不同的产品;抽象这种东西,在六大基本原则就知道了,抽象是要抽象的,问题是为什么还需要一个工厂呢,直接new一个产品不行吗?感觉像是构造者模式的Director部分一样,没什么用呀

有这个疑问也很正常,我在看了这篇文章(工厂设计模式有什么用?)后,好像有了一点点理解;本质上是封装了new一个具体的classA的细节,将变化控制在工厂之中;如果classA的构造改变了,或者需要改为使用classB了,可以在工厂方法里面修改而不需要修改调用者,这样实现解耦,遵循开闭原则

我感觉好像和依赖注入差不多一个意思,我们为了不耦合,所以不自己去创建对象,使用注入进来的对象,现在我们为了不耦合也可以使用工厂注入对象,可能差不多吧

总结

感觉大概多使用就理解了吧

相关文章

  • 设计模式-3种工厂模式

    工厂模式包括:简单工厂模式,工厂方法模式,抽象工厂模式 简单工厂模式 工厂方法根据参数直接创建实例:工厂->产品 ...

  • 设计模式-工厂模式

    工厂模式概念 实例化对象,用工厂方法代替new操作。工厂模式包括工厂方法模式和抽象工厂模式。抽象工厂模式是工厂模式...

  • 设计模式-工厂方法模式

    1、工厂方法模式(Factory Method) 工厂方法模式分为三种: 普通工厂模式 多个工厂模式 静态工厂模式...

  • 设计模式 工厂模式

    工厂模式 工厂模式三大类1、简单工厂模式(静态工厂方法模式)2、工厂方法模式3、抽象工厂模式(Kit模式) 简单工...

  • python设计模式 - 工厂模式之工厂方法

    python 环境 工厂方法模式简介 工厂方法模式Factory Method,又称多态性工厂模式。在工厂方法模式...

  • 第一章2.0工厂- 基础类准备

    2.1工厂-简单工厂模式2.2工厂-工厂方法模式2.3工厂-抽象工厂模式

  • 建造模式

    包括:简单工厂、工厂方法、抽象工厂、单例模式、多例模式、建造模式、原始原型模式。 简单工厂:又名静态工厂方法模式,...

  • PHP-浅谈单例模式和工厂模式

    PHP中常用的设计模式有单例模式、工厂模式(简单工厂模式、工厂方法模式和抽象工厂方法模式)、适配模式、策略模式。 ...

  • 设计模式学习--工厂方法模式

    模式定义 工厂方法模式又称工厂模式,也叫虚拟构造器模式或者多态工厂模式,它属于类创建型模式。在工厂方法模式中,工厂...

  • 五分钟精通设计模式(三)之工厂方法模式

    工厂方法模式分为三种: 普通工厂方法模式、多个工厂方法模式、静态工厂方法模式 废话不多说,下面直奔主题,实现步骤:...

网友评论

      本文标题:工厂方法模式

      本文链接:https://www.haomeiwen.com/subject/hohcsqtx.html