java简单工厂模式是啥
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java简单工厂模式是啥相关的知识,希望对你有一定的参考价值。
能不能写个小例子给我参考下
谢谢
那么简单工厂模式是在什么场景下使用呢,下面就以本人的理解举例说明:
就拿登录功能来说,假如应用系统需要支持多种登录方式如:口令认证、域认证(口令认证通常是去数据库中验证用户,而域认证则是需要到微软的域中验证用户)。那么自然的做法就是建立一个各种登录方式都适用的接口,如下图所示:
public interface Login
//登录验证
public boolean verify(String name , String password);
public class DomainLogin implements Login
@Override
public boolean verify(String name, String password)
// TODO Auto-generated method stub
/**
* 业务逻辑
*/
return true;
public class PasswordLogin implements Login
@Override
public boolean verify(String name, String password)
// TODO Auto-generated method stub
/**
* 业务逻辑
*/
return true;
我们还需要一个工厂类LoginManager,根据调用者不同的要求,创建出不同的登录对象并返回。而如果碰到不合法的要求,会返回一个Runtime异常。
public class LoginManager
public static Login factory(String type)
if(type.equals("password"))
return new PasswordLogin();
else if(type.equals("passcode"))
return new DomainLogin();
else
/**
* 这里抛出一个自定义异常会更恰当
*/
throw new RuntimeException("没有找到登录类型");
测试类:
public class Test
public static void main(String[] args)
// TODO Auto-generated method stub
String loginType = "password";
String name = "name";
String password = "password";
Login login = LoginManager.factory(loginType);
boolean bool = login.verify(name, password);
if (bool)
/**
* 业务逻辑
*/
else
/**
* 业务逻辑
*/
简单工厂模式的结构如下图:
我们可以设想一下真实的场景,如果把上面的Test当做一个servlet的话,当客户端发起登录请求——>请求交给服务端的Servlet——>Servlet根据客户端传递的loginType调用工厂类LoginManager的factory()方法——>factory()方法根据参数loginType创建相应的登录验证类(DomainLogin或PasswordLogin)并返回——>登录验证类调用方法verify()验证用户名密码是否正确
假如不使用简单工厂模式则验证登录Servlet代码如下(假设Test为一个Servlet,变量loginType、name、password表示从客户端传递过来的参数):
public class Test
public static void main(String[] args)
// TODO Auto-generated method stub
String loginType = "password";
String name = "name";
String password = "password";
//处理口令认证
if(loginType.equals("password"))
PasswordLogin passwordLogin = new PasswordLogin();
boolean bool = passwordLogin.verify(name, password);
if (bool)
/**
* 业务逻辑
*/
else
/**
* 业务逻辑
*/
//处理域认证
else if(loginType.equals("passcode"))
DomainLogin domainLogin = new DomainLogin();
boolean bool = domainLogin.verify(name, password);
if (bool)
/**
* 业务逻辑
*/
else
/**
* 业务逻辑
*/
else
/**
* 业务逻辑
*/
上面的代码会不会很蛋疼啊。。。呵呵
《JAVA与模式》一书中使用java.text.DataFormat类作为简单工厂模式的典型例子叙述。
简单工厂模式的优点
模式的核心是工厂类。这个类含有必要的逻辑判断,可以决定在什么时候创建哪一个登录验证类的实例,而调用者则可以免除直接创建对象的责任。简单工厂模式通过这种做法实现了对责任的分割,当系统引入新的登录方式的时候无需修改调用者。
简单工厂模式的缺点
这个工厂类集中了所以的创建逻辑,当有复杂的多层次等级结构时,所有的业务逻辑都在这个工厂类中实现。什么时候它不能工作了,整个系统都会受到影响。 参考技术A 就是专门写一个类,他有一个方法根据传入的参数不同,返回不同的对象。
比如有一台自动售货机AutoSeller, 然后它卖很多饮料Drink, 有茶Tea, 有可乐Cola, 当你去买的时候,你可能是通过按不同的按钮,但对AutoSeller的实现来说,他可能都是同样的方法,只是根据不同的参数(按钮),返回给你不同的对象(Tea或Cola)。
public interface Drink
enum Type TEA, COLA;
public Tea implements Drink
public Cola implements Drink
public class AutoSeller //工厂
public static Drink getDrink(Drink.Type type)
switch(type)
case TEA:
return new Tea();
case COLA:
return new Cola();
default:break;
如上, 在你选择饮料按下按钮里, 自动售货机的代码可能只要执行AutoSeller.getDrink(type)就可以返回你想要的饮料了。
之所以要把Drink定义成接口,一般来讲,用这种架构的话, Drink里面会声明一些接口方法, 这些方法是Tea和Cola都需要的, 但Drink不用关心方法的具体实现, 具体实现只要由Tea和Cola去完成。
而你通过AutoSeller.getDrink(type)去拿到一个Drink对象后,可以用这个对象直接去调Drink中声明的方法。 参考技术B
所谓简单工厂模式, 就是将容易变化的地方, 考虑用一个独立Class来进行创造实体(Object)的过程.
目的: 合并创造实体的动作, 统一以变量处理之. 使得新增实体种类时, 可以不修改到已有程序.
举例来说,
* 虚拟码, 不可执行.
* 假设进行加减乘除运算, 分别使用不同的物件, 对变量A, B进行运算.
// 简单工厂模式的写法 (已宣告完加减乘除类别, 父类别Operation)class OperationFactory
Operation createOperate(string operate)
Operation operr = null;
switch (operate)
case "+":
oper = new OperationAdd();
break;
case "-":
oper = new OperationSub();
break;
case "*":
oper = new OperationMul();
break;
case "/":
oper = new OperationDiv();
break;
return oper;
Operation oper;
oper = OperationFactory.createOperate("+");
oper.NumberA = 1;
oper.NumberB = 2;
result = oper.GetResult();
范例来源: 大话设计模式 - 悦之文化出版
参考技术C 简单工厂模式就是把创建对象的方法封装起来。如:public class Animal
private String id;
private String name;
public class Tiger extends Animal
private String id;
private String name;
本回答被提问者和网友采纳 参考技术D 接着楼上写
public class Animal
public class Cat extends Animal
public class Dog extends Animal
public class Fish extends Animal
/** 工厂类 */
public class AnimalFactory
public static getAnimal(String name)
Animal animal = null;
if("Cat".equals(name))
animal = new Cat();
else if("Dog".equals(name))
animal = new Dog();
else if("Fish".equals(name))
animal = new Fish();
return animal;
public class Test
public static void main(String[] args)
Animal a1 = AnimalFactory.getAnimal("Cat");
Java,设计模式,简单工厂。
一究所编写一个通用程序,用来计算每一种交通工具运行1000公里所需的时间,已知每种交通工具的参数都是3个整数A、B、C的表达式。现有两种工具:Car007 和Plane,其中Car007 的速度运算公式为:A*B/C,Plane 的速度运算公式为:A+B+C。需要编写三类:ComputeTime.java,Plane.java,Car007.java和接口Common.java,要求在未来如果增加第3种交通工具的时候,不必修改以前的任何程序,只需要编写新的交通工具的程序。 Common.java生成的类放在package pkg1.pkg2中; Plane.java生成的类放在package pkg1中; Car007.java生成的类放在package pkg1中; ComputeTime.java不放在任何包中; 其运行过程如下,从命令行输入ComputeTime的四个参数,第一个是交通工具的类型,第二、三、四个参数分别时整数A、B、C,举例如下: 计算Plane的时间:"java ComputeTime Plane 20 30 40" 计算Car007的时间:"java ComputeTime Car007 23 34 45" 如果第3种交通工具为Ship,则只需要编写Ship.java,运行时输入:"java ComputeTime Ship 22 33 44" 提示:充分利用接口的概念,接口对象充当参数。 实例化一个对象的另外一种办法:Class.forName(str).newInstance();例如需要实例化一个Plane对象的话,则只要调用Class.forName("Plane").newInstance()便可。采用通用的方式,则书写如下:(args[0]中存放的是交通工具的类型) Common d=(Common)Class.forName("pkg1."+args[0]).newInstance()。
这个问题很简单啊,就是一个接口,N个具体类,然后创建一个抽象工厂根据传入的类名生成不同的处理类。首先看看工程结构图:
Common接口:
package pkg1.pkg2;
/**
* Common计算接口
*
* @author
*
*/
public interface Common
// 接口方法返回结算结果
public long calulate(int a, int b, int c);
package pkg1;
import pkg1.pkg2.Common;
/**
* Car007具体实现
*
* @author
*
*/
public class Car007 implements Common
public long calulate(int a, int b, int c)
return a * b / c;
package pkg1;
import pkg1.pkg2.Common;
/**
* Plane具体实现
*
* @author
*
*/
public class Plane implements Common
public long calulate(int a, int b, int c)
return a + b + c;
import pkg1.pkg2.Common;
/**
* 主程序应用方法
*
* @author
*
*/
public class ComputeTime
/**
* 获得Common对象
*
* @param clazz
* @return
*/
public static Common getCommonObject(String clazz)
Common common = null;
// 生成接口对象
try
common = (Common) Class.forName("pkg1." + clazz).newInstance();
catch (InstantiationException e)
e.printStackTrace();
catch (IllegalAccessException e)
e.printStackTrace();
catch (ClassNotFoundException e)
e.printStackTrace();
return common;
/**
* 计算运行distance所需要的时间
*
* @param distance
* 距离
* @param common
* 计算速度的接口对象
* @param a
* @param b
* @param c
* @return
*/
public static double calulate(long distance, Common common, int a, int b, int c)
if ( common != null ) return distance / common.calulate(a, b, c);
return 0;
/**
* 主程序方法
*
* @param args
*/
public static void main(String[] args)
if ( args == null || args.length < 4 )
System.out.println("参数个数不正确!正确格式:java ComputeTime XX A B C");
return;
// 获得a
int a = Integer.parseInt(args[1]);
// 获得b
int b = Integer.parseInt(args[2]);
// 获得c
int c = Integer.parseInt(args[3]);
// 计算1000公里的时间
System.out.println(args[0]+"运行1000公里所需的时间为:"+calulate(1000, getCommonObject(args[0]), a, b, c)+"小时");
最后程序运行结果:
Microsoft Windows XP [版本 5.1.2600]
(C) 版权所有 1985-2001 Microsoft Corp.
E:\\>cd E:\\workspace\\test\\bin
E:\\workspace\\test\\bin>java ComputeTime Plane 20 30 40
Plane运行1000公里所需的时间为:11.0小时
E:\\workspace\\test\\bin>java ComputeTime Car007 23 34 45
Car007运行1000公里所需的时间为:58.0小时
E:\\workspace\\test\\bin>
参考技术A 不会以上是关于java简单工厂模式是啥的主要内容,如果未能解决你的问题,请参考以下文章