工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

1. 为什么要有工厂模式?

"Talk is cheap,show me the code". 想要找到这个问题的答案,我们先来看看下面这个项目。

1.1  一个实体类

public class User{

    public String username;
public String password;
}

为了更方便讲述,我尽量让代码精简,方便我们深入了解想关注的点。

实体类很简单,User对象,两个成员变量,username 用户名称,password 用户密码

1.2 定义了一个IUser接口

也很简单,只有一个insert方法

import com.xingyun.model.User;

public interface IUser {
void insert(User user);
}

1.3 一个实现类IUserMySQLImpl.java

import com.xingyun.model.User;
import com.xingyun.myinterface.IUser; public class IUserMySQLImpl implements IUser{ @Override
public void insert(User user) {
// TODO Auto-generated method stub
System.out.println("insert to MySQL"+user.toString());
}
}

这个实现类实现了IUser接口,所以需要实现IUser接口定义的insert(User user)方法.

1.4 最后我们可能需要再多个地方调用

Test1.java

import com.xingyun.model.User;
import com.xingyun.myinterface.IUser;
import com.xingyun.myinterface.impl.IUserMySQLImpl; public class Test1 { public static void main(String[] args) {
// TODO Auto-generated method stub User user=new User();
user.username="admin";
user.password="root"; IUser test=new IUserMySQLImpl();
test.insert(user);
}
}

Test2.java

import com.xingyun.model.User;
import com.xingyun.myinterface.IUser;
import com.xingyun.myinterface.impl.IUserMySQLImpl; public class Test2 { public static void main(String[] args) {
// TODO Auto-generated method stub User user=new User();
user.username="admin";
user.password="root"; IUser test=new IUserMySQLImpl();
test.insert(user);
} }

我们可以发现Test1.java 和Test2.java 中调用方式都是这样:

IUser test=new IUserMySQLImpl();

test.insert(user);

但是假设后来项目中MySQL不想用了,想换Oracle 数据库了怎么办?

1.6 我们需要新写一个实现类 IUserOracleImpl.java

import com.xingyun.model.User;
import com.xingyun.myinterface.IUser; public class IUserOracleImpl implements IUser{ @Override
public void insert(User user) {
// TODO Auto-generated method stub
System.out.println("insert to Oracle"+user.toString());
} }

1.7 这很正常,但是我们之前有多处调用,所以我们将不得不修改Test1.java 和Test2.java,

Test1.java

import com.xingyun.model.User;
import com.xingyun.myinterface.IUser;
import com.xingyun.myinterface.impl.IUserOracleImpl; public class Test1 { public static void main(String[] args) {
// TODO Auto-generated method stub User user=new User();
user.username="admin";
user.password="root"; IUser test=new IUserOracleImpl();
test.insert(user);
}
}

Test2.java

import com.xingyun.model.User;
import com.xingyun.myinterface.IUser;
import com.xingyun.myinterface.impl.IUserOracleImpl; public class Test2 { public static void main(String[] args) {
// TODO Auto-generated method stub User user=new User();
user.username="admin";
user.password="root"; IUser test=new IUserOracleImpl();
test.insert(user);
} }

试想下,假如Test1 ,Test 这类的调用方式有十几处的话,那么这么多地方都要改,我们是不是要累死?

那么如何优化呢?

2. 工厂模式手动实现方式

聪明的大牛做了这样的优化

2.1 实体类不变

public class User{

    public String username;
public String password;
}

2.2 消息接口不变

import com.xingyun.model.User;

public interface IUser {
void insert(User user);
}

2.3 一个实现类IUserMySQLImpl.java

import com.xingyun.model.User;
import com.xingyun.myinterface.IUser; public class IUserMySQLImpl implements IUser{ @Override
public void insert(User user) {
// TODO Auto-generated method stub
System.out.println("insert to MySQL"+user.toString());
}
}

2.4 实现类 IUserOracleImpl.java 不变

import com.xingyun.model.User;
import com.xingyun.myinterface.IUser; public class IUserOracleImpl implements IUser{ @Override
public void insert(User user) {
// TODO Auto-generated method stub
System.out.println("insert to Oracle"+user.toString());
} }

2.5 新建了一个这样的类 IUserFactory.java

import com.xingyun.myinterface.IUser;
import com.xingyun.myinterface.impl.IUserMySQLImpl; public class IUserFactory { public static IUser getIUserImpl() {
return new IUserMySQLImpl();
}
}

2.6 最开始调用方式改变下

Test1.java

import com.xingyun.factory.IUserFactory;
import com.xingyun.model.User;
import com.xingyun.myinterface.IUser; public class Test1 { public static void main(String[] args) {
// TODO Auto-generated method stub User user=new User();
user.username="admin";
user.password="root"; IUser test=IUserFactory.getIUserImpl();
test.insert(user);
}
}

Test2.java

import com.xingyun.factory.IUserFactory;
import com.xingyun.model.User;
import com.xingyun.myinterface.IUser; public class Test2 { public static void main(String[] args) {
// TODO Auto-generated method stub User user=new User();
user.username="admin";
user.password="root"; IUser test=IUserFactory.getIUserImpl();
test.insert(user);
} }

然后将Test1.java和Test2.java 中原来的调用方式

IUser test=new IUserMySQLImpl();
test.insert(user);

改成了这样:

IUser test=IUserFactory.getIUserImpl();
test.insert(user);

于是乎,我当需要将IUserMySQLImpl更换为IUserOracleImpl 的时候,我们只需要修改这个IUserFactory即可,Test1.java和Test2.java 任何调用的地方都不再需要改变。

import com.xingyun.myinterface.IUser;
import com.xingyun.myinterface.impl.IUserOracleImpl; public class IUserFactory { public static IUser getIUserImpl() {
return new IUserOracleImpl();
}
}

你猜的没错,这就是Java 设计模式中著名的工厂模式,通过抽象出一个工厂,来屏蔽调用选择哪一种实现类的,这个问题丢给工厂类来处理切换哪一个实现类。

2. 工厂模式Spring IOC实现方式

Mark:https://www.cnblogs.com/cowboys/p/6638484.html

待续。。。

Java设计模式之工厂模式的两种实现方式的更多相关文章

  1. Java设计模式之工厂模式(Factory模式)介绍(转载)

    原文见:http://www.jb51.net/article/62068.htm 这篇文章主要介绍了Java设计模式之工厂模式(Factory模式)介绍,本文讲解了为何使用工厂模式.工厂方法.抽象工 ...

  2. Java 设计模式之工厂模式(二)

    原文地址:Java 设计模式之工厂模式(二) 博客地址:http://www.extlight.com 一.背景 本篇内容是 Java 设计模式创建型模式的第二篇.上一篇主题为 <Java 设计 ...

  3. java设计模式2————工厂模式

    1.工厂模式介绍: 1.1.实现了创建者与调用者的分离 1.2.详细分类: 简单工厂模式 工厂方法模式 抽象工厂模式 1.3.所遵循的OOP原则: 开闭原则:对扩展开放,对修改关闭 依赖倒转原则:面向 ...

  4. 浅析JAVA设计模式之工厂模式(一)

    1 工厂模式简单介绍 工厂模式的定义:简单地说,用来实例化对象,取代new操作. 工厂模式专门负责将大量有共同接口的类实例化.工作模式能够动态决定将哪一个类实例化.不用先知道每次要实例化哪一个类. 工 ...

  5. 浅析JAVA设计模式之工厂模式(二)

    1 工厂方法模式简单介绍 工厂方法 (Factroy Method)模式:又称多态性工厂模式(Polymorphic Factory),在这样的模式中,核心工厂不再是一个详细的类.而是一个抽象工厂,提 ...

  6. Java设计模式之-----工厂模式(简单工厂,抽象工厂)

    一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类:1)简单工厂模式(Simple Factor ...

  7. Java设计模式之工厂模式(简单工厂模式+工厂方法模式)

    摘自http://blog.csdn.net/jason0539/article/details/23020989 在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是 ...

  8. 3.java设计模式之工厂模式

    基本需求: 一个披萨店需要订购不同种类的披萨 传统方式: 实现思路 在订购类中根据用户不同的输入直接创建不同的披萨实体类进行返回 UML类图 代码实现 披萨类 // 抽象父类 public abstr ...

  9. 女娲造人引发思考之Java设计模式:工厂模式

    目录 工厂模式的几种形态 简单工厂模式 示例 结构 优缺点 女娲抟土造人 工厂方法模式 结构 女娲举绳造人 抽象工厂模式 结构 女娲造万物 工厂模式的几种形态 工厂模式专门负责将大量有共同接口的类实例 ...

随机推荐

  1. 转发:centos彻底删除文件夹、文件命令(centos 新建、删除、移动、复制等命令)

    http://blog.csdn.net/lpdx111/article/details/16877725 centos彻底删除文件夹.文件命令(centos 新建.删除.移动.复制等命令: 1.新建 ...

  2. Oracle内存结构:SGA PGA UGA

    内存结构是oracle数据库最重要的组成部分之一,在数据库中的操作或多或少都会依赖到内存,是影响数据库性能的重要因素Oracle数据库中包括3个基本的内存结构: 一. 系统全局区  (System G ...

  3. iOSUIWebView---快停下啦,你的愚蠢的行为

    公元前 之前还是学生时代的时候给社团们学弟学妹们介绍iOS编程的时候,简单的准备了图灵ios培训第一周(使用UIWebView创建简易浏览器), NSURL *url =[NSURL URLWithS ...

  4. java 遍历Map的四种方式

      java 遍历Map的四种方式 CreationTime--2018年7月16日16点15分 Author:Marydon 一.迭代key&value 第一种方式:迭代entrySet 1 ...

  5. Xamarin.Android之SlidingMenu

    一.前言 有位网友在评论中希望能够出个在Xamarin.Android下实现SlidingMenu效果的随笔,刚好昨天在观看官网示例项目的时候也看到这个SlidingMenu,但是最终的效果并不是我们 ...

  6. where常用运算符

    mysql查询的五种子句:where(条件查询).having(筛选).group by(分组).order by(排序).limit(限制结果数) where常用运算符:比较运算符> , &l ...

  7. Centos7.4下keepalived-1.3.5的安装使用

    keepalived两个功能,一个是使lvs使用的vip高可用,一个是监控下游各个子节点的对应端口是否正常工作,以保证快速剔除坏掉的节点. keepalived默认的yum 1.3.5有BUG,根本跑 ...

  8. vsftp 虚拟用户测试

    1.创建用于进行FTP验证的帐号密码数据库文件,单数行为账户名,偶数行为密码.[root@rhel1 vsftpd]# vi /etc/vsftpd/vuser.listuser1123456user ...

  9. ORA-01034: ORACLE not available解决

    问题现象: alter user scott account unlock; ERROR at line 1:ORA-01034: ORACLE not availableProcess ID: 0S ...

  10. windows上的Qt 5的依赖部署打包

    通常我们编译Qt程序的时候最终会生成exe或dll,这些可执行文件都会有Qt模块的依赖,如果项目一旦庞大,就不是很好看出缺了什么模块,导致安装包安装到其他绿色干净的windows机器上会提示缺少XXX ...