简单工厂模式是类的创建模式,又叫做静态工厂方法(Static Factory Method)模式。简单工厂模式是由一个工厂对象决定创建出那一种产品类的实例。
1. 工厂模式的几种形态
工厂模式专门负责将大量有共同接口的类实例化。工厂模式可以动态决定将哪一个类
实例化,不必事先知道每次要实例化哪一个类。工厂模式有以下几种形态:
(1)简单工厂(Simple Factory)模式,又称静态工厂方法模式(Static Factory Method Pattern)。
(2)工厂方法(Factory Method)模式,又称多态性工厂(Polymorphic Factory)模式或虚拟构造子(Virtual Constructor)模式;
(3)抽象工厂(Abstract Factory)模式,又称工具箱(Kit 或Toolkit)模式。
下面就是简单工厂模式的简略类图。
简单工厂模式,或称静态工厂方法模式,是不同的工厂方法模式的一个特殊实现。在其他文献中,简单工厂往往作为普通工厂模式的一个特例讨论。
在Java语言中,通常的工厂方法模式不能通过设计功能的退化给出静态工厂方法模式。
因为一个方法是不是静态的,对于Java 语言来说是一个很大的区别,必须在一开始的时候就加以考虑。这就是本人将简单工厂单独提出来讨论的一个原因。学习简单工厂模式是对学习工厂方法模式的一个很好的准备,也是对学习其他模式的一个很好的准备。
2. 简单工厂模式的引进
简单工厂模式又叫静态工厂模式,顾名思义,它是用来实例化目标类的静态类。下面我主要通过一个简单的实例说明简单工厂及其优点。
现在我们通过一个例子看一下:
比如说有一个汽车公司,专门向市场销售各牌子的汽车。我们做一个相应的系统(例子):
首先我们把汽车堪称是一个接口注1,在这个接口里面有两个抽象方法—进货及卖(销售汽车)。然后根据需要去实现这个接口。
注1:在面向对象设计方法中有很多值得提倡的方法,这些方法可以为我们的设计带来很大的灵活性,可复用性。其中一个原则就是“针对接口编程,而不是针对实现编程” 。这个原则带来的好处有以下几点:
l Client不必知道其使用对象的具体所属类。
l Client无需知道特定类,只需知道他们所期望的接口。
l 一个对象可以很容易地被(实现了相同接口的)的另一个对象所替换。
l 对象间的连接不必硬绑定(hardwire)到一个具体类的对象上,因此增加了灵活性。
在接口完成(interface Car)了、汽车的概念已经出来以后,我们要去实现这个接口(根据我们想要销售的汽车类型,例如奔驰、福特、……等)。
这个时候,如果我们要销售奔驰车,就要在main方法(客户端)去实例化一个“class Benz”,并在客户端(main方法)中去实例化相关对象和调用对应的方法。
运行程序,正常。
这个时候如果我们想销售福特了,怎么办?这个时候我必须去修改客户端的程序(main方法),把Car c=new Benz();改成Car c=new Ford();。改动就有可能出错误,就要进行测试,……,这样显然对程序是不利的。我们应当怎样解决这个问题呢?
我们就想到,我们可以加一个工厂类,让这个工厂类为客户端实例化一个对象:
到目前为止,这个程序就是一个简单的工厂模式,但是这里还存在着一个问题:在我的客户端(main方法的地方),我需要即可以要Benz也可以要Ford,可以动态的去选择它,该怎么办呢?
这个时候我们就在想,我们可以把在class Factory中的getCarInstance()方法进行改进,让该方法可以接收参数,也就是说,客户端想要什么,我的工厂就按照客户端的要求去提供,首先对class Factory中的getCarInstance()进行改进,然后客户端程序也做相应的调整:
运行正常。但是现在还有问题:在传递参数的时候只能传入Benz或者Ford,如果传入其它参数就会出问题,怎么办呢?应当在客户端这里加一个判断,看Factory.getCarInstance(“Benz”);返回的参数是不是“空”的:
现在又有一个问题,如果我们不仅卖奔驰和福特,我们还卖别的牌子的汽车,也就是说如果我们现在要扩充一个子类,就必须去修改“工厂”(class Factory),在“工厂”中在添加一个if去判断并去实例化相应的子类,例如我们想要销售丰田汽车,就必须修改“工厂”。怎样解决这个问题呢?
我们现在要解决的问题是,扩充子类,怎样不用去修改工厂:如果是用java语言来实现的话,我们自然会想到利用java的反射机制注2 ,
注2:java的反射机制:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
用java的反射机制解决这个问题,那么在“工厂”中就不用if判断了,
这个时候在客户端的Car c=Factory.getCarInstance(“Benz”);中无论是输入Benz还是输入Ford都会等到正确的运行结果。完整的程序如下:
package org.chenb.factorydemo;
interface Car{
public void stock();
public void sell();
}
class Benz implements Car{
public void stock(){
System.out.println("Benz进货了………");
}
public void sell(){
System.out.println("Benz卖出了………");
}
}
class Ford implements Car{
public void stock(){
System.out.println("Ford进货了………");
}
public void sell(){
System.out.println("Ford卖出了………");
}
}
class Factory{
public static Car getCarInstance(String type){
Car c=null;
try {
c=(Car)Class.forName("org.chenb.factorydemo."+type).newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return c;
}
}
public class FactoryDemo {
public static void main(String[] args) {
Car c=Factory.getCarInstance("Benz");
if(c!=null){
c.stock();
c.sell();
}else{
System.out.println("无此类型的汽车销售……");
}
}
}
这个时候,如果我们添加一个子类,比如我们除销售奔驰、福特以外,还要销售丰田、奇瑞,就不需要去修改工厂了,只要去添加一个子类即可,例如我们要销售丰田汽车了,就添加一个子类Toyota去实现汽车接口:
class Toyota implements Car{
public void stock(){
System.out.println("Toyota进货了………");
}
public void sell(){
System.out.println("Toyota卖出了………");
}
}
在客户端的Car c=Factory.getCarInstance(“Toyota”);中输入Toyota即可。
其实这也实现了面对对象设计的一个很重要的原则—开闭原则(OCP),即一个软件实体应当对扩展开放,对修改关闭。
分享到:
相关推荐
6 抽象工厂模式 7 建造者模式 8 代理模式 9 装饰模式 10 原型模式 11 委派模式 12 适配器模式 设计模式综合运用 1 门面+模版方法+责任链+策略 2 门面+模版方法+责任链+策略+工厂方法 3 动态代理+Spring AOP 4 责任链...
抽象工厂模式是一种创建型设计模式,它提供了一个接口,用于创建相关或依赖对象的家族,而无需指定它们的具体类。在.NET框架中,我们可以利用接口和抽象类来实现这一模式。 在.NET中,抽象工厂模式通常通过定义一...
1. 工厂模式(Factory Pattern): 工厂模式提供了一个创建对象的接口,但允许子类决定实例化哪一个类。它将对象的创建过程封装起来,使得系统可以更加灵活,同时也降低了代码间的耦合度。例如,你可以创建一个抽象...
1. **工厂模式(Factory Mode)**:这是最基础的设计模式之一,用于创建对象,通过提供一个接口来实例化对象,而不是直接暴露具体的类。在`FacotryMode`中,你可以看到如何使用工厂方法或者抽象工厂模式来创建对象,...
设计模式综合运用:主要是笔者在实际工作中运用到的一些设计模式综合运用事例的提炼 Spring设计模式简介:主要是讲述Spring源码中运用到的一些设计模式(将来增加) Ibatis设计模式简介:主要是讲述Ibatis源码中运用...
java设计模式-创建者模式-简单工厂模式。详细的讲解了什么是工厂方法模式及应用场景和应用场景的代码事例。及各工厂模式的区别。
简单工厂模式是软件设计模式中的一种,它提供了一种创建对象的最佳方式,特别是在类的实例化需要依赖于某些条件时。在这个"关于简单工厂模式的一个java例子"中,我们将深入探讨这种模式的基本概念、实现方式以及它在...
在编程领域,设计模式是一种被广泛认可的解决常见问题的最佳实践。C# 作为一种面向对象的编程语言,其丰富的特性使得它非常适合实现各种设计模式。以下是对标题和描述中提及的C#设计模式的详细解释: 1. **单例模式...
2. 设计模式综合运用:主要是笔者在实际工作中运用到的一些设计模式综合运用事例的提炼 3. Spring设计模式简介:主要是讲述Spring源码中运用到的一些设计模式 4. Ibatis设计模式简介:主要是讲述Ibatis源码中运用到...
策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。在软件工程中,我们经常遇到需要根据不同条件或场景动态调整算法的情况,策略模式便为此提供了优雅的解决方案。在这个例子中,我们将通过HerdFirst...
策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。在软件工程中,当一个系统需要在不同时间执行不同的算法或者行为时,策略模式就显得尤为有用。这种模式将算法封装到独立的可相互替换的策略类中,使得...
这是我经常使用的设计模式迷你手册, 非常简洁,包含所有的设计模式, 有图例,简介,和C++ 程序事例。
在.NET开发环境中,抽象工厂模式是一种常用的创建型设计模式,它提供了一种创建对象的接口,使得子类能够决定实例化哪些类。这种模式在C#编程中特别有用,因为它可以帮助我们实现平台或框架无关的代码,使得系统更加...
Smalltalk 语言和 Java 语言有很多相似性,都是面向对象语言,很自然的 SUN 在 Petstore(宠物店)事例应用程序中就推荐 MVC 模式作为开发 Web 应用的架构模式。 MVC 模式是一个复杂的架构模式,其实现也显得非常...
- **工厂模式**:提供一个创建对象的接口,但让子类决定实例化哪一个类,使代码更灵活,易于扩展。 - **观察者模式**(Observer):定义了对象间的一对多依赖关系,当一个对象的状态改变时,所有依赖于它的对象...
设计模式综合运用:主要是作者在实际工作中运用到一些设计模式综合运用事例的提炼 Spring设计模式简介:主要讲述Spring源码中运用到的一些设计模式(未来增加) Ibatis设计模式简介:主要是讲述Ibatis源码中运用到的...
简单工厂模式是软件设计领域中一种常见的创建型设计模式,它提供了一种创建对象的最佳方式。在JavaScript这种基于原型继承的动态语言中,简单工厂模式同样有着广泛的应用。简单工厂模式的核心思想是将对象的创建与...