设计模式系列之二:工厂方法模式

前言

前一篇博文中介绍了简单工厂模式,这里再介绍一下工厂方法模式。与简单工厂很像,那么两者的区别是什么呢?在这篇博文中,首先会简单介绍一下工厂方法的使用方法,并对工厂方法模式进行简单的小结。最后,将结合具体的例子对比简单工厂模式与工厂方法模式,并对两者的使用场景做一个小小的归纳。

问题背景

背景: 某公司开发了一个A软件,数据库使用的是SQLServer。后由于客户要求需要使用Oracle数据库,原来的数据要迁移到Oracle中,在迁移的过程中遇到很多问题,比如语法错误,关键字滥用,函数不支持等问题。请设计一组程序,实现数据的无缝迁移

工厂方法模式

介绍

问题背景与工厂方法一样,主要是为了便于对两者进行比较。ok,为了对工厂方法有一个更好的理解,请看下面的结构图:

实现

于是,我们根据上面的结构图可以写出如下的代码:

//User对象
public class User {
    private int id;
    private String name;
    //此处省略setter与getter方法
}
//数据库对象父类
public abstract class DBObject {
    //添加用户的方法
    public abstract void insertUser(User user);
    //查找用户信息的方法
    public abstract User findUserById(int id);
}
//具体的Oracle对象
public class OracleObject extends DBObject{
    @Override
    public void insertUser(User user) {
        System.out.println("使用Oracle添加用户");
    }
    @Override
    public User findUserById(int id) {
        System.out.println("使用Oracle通过id找到用户");
        return null;
    }
}
//具体的SqlServer对象
public class SqlServerObejct extends DBObject{
    @Override
    public void insertUser(User user) {
        System.out.println("使用SQLServer添加用户");
    }
    @Override
    public User findUserById(int id) {
        System.out.println("使用SQLServer通过id找到用户");
        return null;
    }
}
//工厂的抽象接口
public interface IDBObjectFactory {
    DBObject createDBObject();
}
//Oracle数据库对象的工厂,作用是创建Oracle对象
public class OracleObjectFactory implements IDBObjectFactory{
    @Override
    public DBObject createDBObject() {
        return new OracleObject();
    }
}
//SqlServer数据库对象的工厂类,作用是创建SqlServer的对象
public class SqlServerObjectFactory implements IDBObjectFactory{
    @Override
    public DBObject createDBObject() {
        return new SqlServerObejct();
    }
}
//测试方法
public static void main(String[] args) {
    User user = new User();
    IDBObjectFactory dbObjectFactory = new OracleObjectFactory();
    DBObject dbObject = dbObjectFactory.createDBObject();
    dbObject.insertUser(user);
    dbObject.findUserById(1);
}

测试结果:
使用Oracle添加用户
使用Oracle通过id找到用户

ok,通过上面的程序,我们来回顾一下工厂方法的定义:

工厂方法定义一个用于创建对象的接口,让子类去决定实例化哪个对象。创建对象延迟到子类中

工厂方法模式小结

  • 把创建对象延迟到子类中,由子类决定创建何种类型的实例
  • 当需要增加功能时,只需要直接修改客户端而保持其他代码不变就可以实现

工厂方法 vs 简单工厂

回到上一篇博文中,假设有三个客户需要使用Oracle对象,那么我们在代码中这么实现的:

DBObject db1 = DBFactory.createDBObject("oracle");
DBObject db2 = DBFactory.createDBObject("oracle");
DBObject db3 = DBFactory.createDBObject("oracle");
//调用查找以及添加的方法,这里省略

好,这样写并没有什么问题,假如这三个用户觉得Oracle不好用,要改用SqlServer对象,怎么办?简单,直接把上面的代码中的oracle改为sqlserver不久行了嘛,所以修改之后的代码这样的:

DBObject db1 = DBFactory.createDBObject("sqlserver");
DBObject db2 = DBFactory.createDBObject("sqlserver");
DBObject db3 = DBFactory.createDBObject("sqlserver");

代码改好了,很简单,有木有,确实。但是加入不是三个用户而是一亿个用户呢?难道要改一亿次,明显不太现实(可能有人说,一亿算个啥,用ctrl+h直接一替换不久完事了吗。我们在讨论设计模式,不带这么玩的哈,这不科学!)

而我们使用工厂方法模式只需要修改上面测试方法中的工厂对象就可以

//测试方法
public static void main(String[] args) {
    User user = new User();
    //把OracleObjectFactory修改为SqlServerObjectFactory就可以
    IDBObjectFactory dbObjectFactory = new OracleObjectFactory();
    DBObject dbObject1 = dbObjectFactory.createDBObject();
    DBObject dbObject2 = dbObjectFactory.createDBObject();
    DBObject dbObject3 = dbObjectFactory.createDBObject();
    //调用添加或者查找方法
}

通过这个例子,可以发现简单工厂模式违背了对外扩展开放,对内修改关闭的原则,因为当需要增加MySQL对象的时候,需要在工厂方法模式中添加switch的语句分支的判断,而在工厂方法模式中,只需要创建一个MySQL对象工厂类(需要实现IDBObjectFactory接口)就可以了,代码比较简单就不附上代码了。

时间: 2025-01-18 18:17:47

设计模式系列之二:工厂方法模式的相关文章

Java设计模式编程中的工厂方法模式和抽象工厂模式_java

工厂方法模式 动机 创建一个对象往往需要复杂的过程,所以不适合包含在一个复合工厂中,当有新的产品时,需要修改这个复合的工厂,不利于扩展. 而且,有些对象的创建可以需要用到复合工厂访问不到的信息,所以,定义一个工厂接口,通过实现这个接口来决定实例化那个产品,这就是工厂方法模式,让类的实例化推迟到子类中进行. 目的 1. 定义一个接口,让子类决定实例化哪个产品. 2. 通过通用接口创建对象. 实现 1. 产品接口和具体产品很好理解. 2. 工厂类提供一个工厂方法,返回一个产品对象.但是这个工厂方法是

设计模式详解之工厂方法模式

工厂方法模式(Factory Method)分为3种: 1.普通工厂模式 就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建.首先看下关系图: 我们以一个例子来讲解:发送短信和发送邮件(具有共同的接口:发送) 接口: public interface Sender { /* * 发送邮件或者短消息的共同接口 */ public void sender(); } 实现类: /* * 发送邮件的实现类 */ public class MailSender implements Sender

Ruby中使用设计模式中的简单工厂模式和工厂方法模式_ruby专题

之前有看过<ruby设计模式>,不过渐渐的都忘记了.现在买了一个大话设计模式,看起来不是那么枯燥,顺便将代码用ruby实现了一下. 简单工厂模式: # -*- encoding: utf-8 -*- #运算类 class Operation attr_accessor :number_a,:number_b def initialize(number_a = nil, number_b = nil) @number_a = number_a @number_b = number_b end d

Android设计模式系列之工厂方法模式_Android

工厂方法模式,往往是设计模式初学者入门的模式,的确,有人称之为最为典型最具启发效果的模式. android中用到了太多的工厂类,其中有用工厂方法模式的,当然也有很多工厂并不是使用工厂方法模式的,只是工具管理类. 今天以ThreadFactory举例说明一下简单工厂模式和工厂方法模式. 工厂方法模式,Factory Method,简单的方式,不简单的应用. 1.意图 定义一个用于创建对象的接口,让子类决定实例化哪个类.工厂方式模式使一个类的实例化延迟到其子类. 热门词汇:虚构造器 延迟 创建对象

炒冷饭系列:设计模式 工厂方法模式

一.什么是工厂方法模式 工厂方法模式同样属于类的创建型模式又被称 为多态工厂模式 .工厂方法模式的意义是定义一个创建 产品对象的工厂接口,将实际创建工作推迟到子类当中. 核心工厂类不再负责产品的创建,这样核心类成为一个 抽象工厂角色,仅负责具体工厂子类必须实现的接口, 这样进一步抽象化的好处是使得工厂方法模式可以使系 统在不修改具体工厂角色的情况下引进新的产品. 二.模式中包含的角色及其职责 1.抽象工厂(Creator)角色 工厂方法模式的核心,任何工厂类都必须实现这个接口. 2.具体工厂(

.NET设计模式-工厂方法模式(Factory Method)

工厂方法模式(Factory Method) --.NET设计模式系列之五 Terrylee,2004年1月2日 概述 在软件系统中,经常面临着"某个对象"的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口.如何应对这种变化?提供一种封装机制来隔离出"这个易变对象"的变化,从而保持系统中"其它依赖该对象的对象"不随着需求的改变而改变?这就是要说的Factory Method模式了. 意图 定义一个用户创

C#设计模式(3)——工厂方法模式

原文:C#设计模式(3)--工厂方法模式 一.引言 在简单工厂模式中讲到简单工厂模式的缺点,有一点是--简单工厂模式系统难以扩展,一旦添加新产品就不得不修改简单工厂方法,这样就会造成简单工厂的实现逻辑过于复杂,然而本专题介绍的工厂方法模式可以解决简单工厂模式中存在的这个问题,下面就具体看看工厂模式是如何解决该问题的. 二.工厂方法模式的实现 工厂方法模式之所以可以解决简单工厂的模式,是因为它的实现把具体产品的创建推迟到子类中,此时工厂类不再负责所有产品的创建,而只是给出具体工厂必须实现的接口,这

【设计模式系列】--简单工厂模式

简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一.简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例.简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现.简单来说,通过专门定义一个类来辅助创建其他类的实例,被创建的实例通常都具有共同的父类,今天这篇博文,小编主要简单的介绍一下简单工程模式,通过简单的demo一步一步进行讲解,希望对有需要的小伙伴有帮助,还请小伙伴们多多指教.

java设计模式之工厂方法模式_java

概要 设计模式是一门艺术,如果真正了解这门艺术,你会发现,世界都将变得更加优美. 定义 定义一个用于创建对象的接口,让其子类去决定实例化那个类 使用场景 任何使用复杂对象的地方,都可以使用工厂模式 UML 1.抽象工厂  抽象工厂:我们都知道,工厂,一般只有一个作用,那就生产,比如,吉利汽车厂,那就制造吉利汽车,iphone手机制造厂就造iphone等等 所以可以用一个简单的方法概括,就是create(); 2.具体汽车制造厂  具体汽车制造厂:实现了抽象工厂,具有实际的制造汽车的流程和方法等