Java设计模式——工厂设计模式
工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类。
工厂模式的形态
工厂模式主要用一下几种形态:
1:简单工厂(Simple Factory)。
2:工厂方法(Factory Method)。
3:抽象工厂(Abstract Factory)。
简单工厂(Simple Factory)
又叫静态工厂,是工厂模式三中状态中结构最为简单的。主要有一个静态方法,用来接受参数,并根据参数来决定返回实现同一接口的不同类的实例。我们来看一个具体的例子:
假设一家工厂,几生产洗衣机,有生产冰箱,还有空调等等..
我们先为所有产品定义一个共同的产品接口
- public interface Product{}
接着我们让这个工厂的所有产品都必须实现此接口
- public class Washerimplements Product{
- public Washer(){
- System.out.println("洗衣机被制造了");
- }
- }
- public class Iceboximplements Product{
- public Icebox(){
- System.out.println("冰箱被制造了");
- }
- }
- public class AirConditionimplements Product{
- public Icebox(){
- System.out.println("空调被制造了");
- }
- }
接下来我们来写一个工厂类,有它来负责生产以上的产品
- public class SimpleFactory {
- public static Product factory(String productName)throws Exception{
- if(productName.equals("Washer")){
- return new Washer();
- }else if(productName.equals("Icebox")){
- return new Icebox();
- }else if(productName.equals("AirCondition")){
- return new AirCondition();
- }else{
- throw new Exception("没有该产品");
- }
- }
- }
好了,有了这个工厂类,我们就可以开始下定单了,SimpleFactory将根据不同的定单类决定生产什么产品。
- public staticvoid main(String[] args) {
- try {
- SimpleFactory.factory("Washer");
- SimpleFactory.factory("Icebox");
- SimpleFactory.factory("AirCondition");
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
由上面的代码可以看出,简单工厂的核心就是一个SimpleFactory类,他拥有必要的逻辑判断能力和所有产品的创建权利,我们只需要向把定单给他,就能得到我们想要的产品。这使用起来似乎非常方便。
但,实际上,这个SimpleFactory有很多的局限。首先,我们每次想要增加一种新产品的时候,都必须修改SimpleFactory的原代码。其次,当我们拥有很多很多产品的时候,而且产品之间又存在复杂的层次关系的时候,这个类必须拥有复杂的逻辑判断能力,其代码量也将不断地激增,这对以后的维护简直就是恐怖两个字...
还有就是,整个系统都严重依赖SimpleFactory类,只要SimpleFactory类一出问题,系统就进入不能工作的状态,这也是最为致命的一点....
以上的不足将在工厂模式的另外两种状态中得到解决。
工厂方法(Factory Method)
上面的代码告诉我们,简单工厂并不简单,它是整个模式的核心,一旦他出了问题,整个模式都将受影响而不能工作,为了降低风险和为日后的维护、扩展做准备,我们需要对它进行重构,引入工厂方法。
工厂方法为工厂类定义了接口,用多态来削弱了工厂类的职能,以下是工厂接口的定义:
- public interface Factory{
- public Product create();
- }
我们再来定义一个产品接口
- public interface Product{}
一下是实现了产品接口的产品类
- public class Washerimplements Product{
- public Washer(){
- System.out.println("洗衣机被制造了");
- }
- }
- public class Iceboximplements Product{
- public Icebox(){
- System.out.println("冰箱被制造了");
- }
- }
- public class AirConditionimplements Product{
- public Icebox(){
- System.out.println("空调被制造了");
- }
- }
接下来,就是工厂方法的核心部分,也就是具体创建产品对象的具体工厂类,
- //创建洗衣机的工厂
- public class CreateWasherimplements Factory{
- public Product create(){
- return new Washer();
- }
- }
- //创建冰箱的工厂
- public class CreateIceboximplements Factory{
- public Product create(){
- return new Icebox();
- }
- }
- //创建空调的工厂
- public class CreateAirConditionimplements Factory{
- public Product create(){
- return new AirCondition();
- }
- }
从上面创建产品对象的代码可以看出,工厂方法和简单工厂的主要区别是,简单工厂是把创建产品的职能都放在一个类里面,而工厂方法则把不同的产品放在实现了工厂接口的不同工厂类里面,这样就算其中一个工厂类出了问题,其他工厂类也能正常工作,互相不受影响,以后增加新产品,也只需要新增一个实现工厂接口工厂类,就能达到,不用修改已有的代码。但工厂方法也有他局限的地方,那就是当面对的产品有复杂的等级结构的时候,例如,工厂除了生产家电外产品,还生产手机产品,这样一来家电是手机就是两大产品家族了,这两大家族下面包含了数量众多的产品,每个产品又有多个型号,这样就形成了一个复杂的产品树了。如果用工厂方法来设计这个产品家族系统,就必须为每个型号的产品创建一个对应的工厂类,当有数百种甚至上千种产品的时候,也必须要有对应的上百成千个工厂类,这就出现了传说的类爆炸,对于以后的维护来说,简直就是一场灾难.....
抽象工厂(Factory Method)
抽象工厂:意的意图在于创建一系列互相关联或互相依赖的对象。<<Java设计模式>>
我自己觉得抽象工厂是在工厂方法的基础上引进了分类管理的概念....
工厂方法用来创建一个产品,它没有分类的概念,而抽象工厂则用于创建一系列产品,所以产品分类成了抽象工厂的重点,
我们继续用上面的例子来说明:
工厂生产的所有产品都用都用大写字母来标明它们的型号,比如冰箱,就有“冰箱-A",“冰箱-B",同样,其他的产品也都是遵守这个编号规则,于是就有了一下产品家族树
冰箱:
- 冰箱-A
- 冰箱-B
洗衣机:
- 洗衣机-A
- 洗衣机-B
我们可以为冰箱和洗衣机分别定义两个产品接口,以对他们进行分类,
- //洗衣机接口
- public interface Washer{
- }
- //冰箱接口
- public interface Icebox{
- }
接着,我们分别创建这两个接口的具体产品
- //洗衣机-A
- public class WasherAimplements Washer{
- public WasherA(){
- System.out.println("洗衣机-A被制造了");
- }
- }
- //洗衣机-B
- public class WasherBimplements Washer{
- public WasherB(){
- System.out.println("洗衣机-B被制造了");
- }
- }
- //冰箱-A
- public class IceboxAimplements Icebox{
- public IceboxA(){
- System.out.println("冰箱-A被制造了");
- }
- }
- //冰箱-B
- public class IceboxBimplements Icebox{
- public IceboxB(){
- System.out.println("冰箱-B被制造了");
- }
- }
到此,产品部分我们准备好了,接下来我们来处理工厂部分,我们先来定义工厂行为接口
- public interface Factory{
- public Washer createWasher();
- public Icebox createIcebox();
- }
接下来我创造具体的工厂类,我们根据上面产品的接口,把型号A的产品分为一类,由一个工厂来管理,把型号为B的产品有另一个工厂管理,根据这个分类,我们可以实现如下的两个具体工厂类
- //创建型号为A的产品工厂
- public class FactoryAimplements Factory{
- //创建洗衣机-A
- public Washer createWasher(){
- return new WasherA();
- }
- //创建冰箱-A
- public Icebox createIcebox(){
- return new IceboxA();
- }
- }
- //创建型号为B的产品工厂
- public class FactoryBimplements Factory{
- //创建洗衣机-B
- public Washer createWasher(){
- return new WasherB();
- }
- //创建冰箱-B
- public Icebox createIcebox(){
- return new IceboxB();
- }
- }
这样,我们的抽象工厂就完成了。有上面可以看出,在运用上我觉得工厂方法和抽象工厂,都有自己的应用场景,并没有什么优劣之分,但在应用抽象工厂之前,要先对创建的对象进行系统的分类,这点很重要,好的产品分类规则能为具体工厂类的选择调用和以后的扩展提供清晰的思路.
Java设计模式——工厂设计模式的更多相关文章
- java简单工厂设计模式
一.基本定义 /* *简单工厂设计模式: *文字描述理解: * 简单工厂模式属于类的创建型模式,又叫做静态工厂方法模式. * 通过专门定义一个类来负责创建其它类的实例,被创建的实例通常 * 都具有共同 ...
- Java设计模式—工厂设计模式
工厂设计模式(减少耦合.通过接口或者工厂类来实现) 耦合性:粘度强(依耐性) Person p = new Person(); //耦合性强 Man p = new Per ...
- php设计模式-工厂设计模式
概念: 工厂设计模式提供获取某个对象的新实例的一个接口,同时使调用代码避免确定实际实例化基类步骤. 很多高级模式都是依赖于工厂模式.
- java设计模式------工厂设计模式
总结 以上就是工厂模式的基本实现和详细说明.包括了简单工厂模式.工厂方法模式.抽象工厂模式.我们可以基于需求来选择合适的工厂模式 基本概念:为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来 ...
- 【51】java设计模式-工厂设计模式剖析
工厂设计设计模式的分类: 工厂模式在<Java与模式>中分为三类: 1)简单工厂模式(Simple Factory):不利于产生系列产品: 2)工厂方法模式(Factory Method) ...
- Java基础-工厂设计模式(三锅的肥鸡)
---恢复内容开始--- 1)还没有工厂时代:假如还没有工业革命,如果一个你要一架飞机,一般的做法是自己去建造一架飞机,然后拿来开 通常的结果就是 有些时候 要么专科螺钉 没打好 要么就是 那个 ...
- Java基础面试操作题:Java代理工厂设计模式 ProxyFactory 有一个Baby类,有Cry行为,Baby可以配一个保姆 但是作为保姆必须遵守保姆协议:能够处理Baby类Cry的行为,如喂奶、哄睡觉。
package com.swift; public class Baby_Baomu_ProxyFactory_Test { public static void main(String[] args ...
- 10.Java设计模式 工厂模式,单例模式
Java 之工厂方法和抽象工厂模式 1. 概念 工厂方法:一抽象产品类派生出多个具体产品类:一抽象工厂类派生出多个具体工厂类:每个具体工厂类只能创建一个具体产品类的实例. 即定义一个创建对象的接口(即 ...
- Java设计模式---工厂模式(简单工厂、工厂方法、抽象工厂)
工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类.工厂模式的形态工厂模式主要用一下几种形态:1:简单工厂(Simple Factory).2:工厂方法(Factory M ...
随机推荐
- 使用fastjson读取超巨json文件引起的GC问题
项目中需要将巨量数据生成的json文件解析,并写入数据库,使用了 alibaba 的 fastjson,在实践过程中遇到了 GC 问题,记录如下: 数据大约为70万条,文件大小在3~4G左右,使用 f ...
- MySQL 事务嵌套
MySQL默认自动提交(autocommit=1),如果要开启事务,先关闭自动提交(autocommit=0): InnoDB支持事务,MyISAM不支持: MySQL不支持事务嵌套:已经开启事务后, ...
- jQuery-ajax-.load方法
使用jQuery封装的ajax是非常好用的,这个里面提供了几个比较好用的方法. load(url[,data, callback])方法: 说明:这个是jQuery中的最底层方法$.ajax()封装的 ...
- Docker安装nacos1.0.0固定ip单机模式
1 从dockerHub拉取镜像到本地 docker pull nacos/nacos-server:1.0.0 2 创建目录(宿主机) 2.1 日志目录 mkdir -p /docker/nacos ...
- 算法与数据结构基础 - 堆栈(Stack)
堆栈基础 堆栈(stack)具有“后进先出”的特性,利用这个特性我们可以用堆栈来解决这样一类问题:后续的输入会影响到前面的阶段性结果.线性地遍历输入并用stack处理,这类问题较简单,求解时间复杂度一 ...
- esxi虚机迁移到Workstation
虚拟机的文件管理由VMware Workstation来执行.一个虚拟机一般以一系列文件的形式储存在宿主机中,这些文件一般在由workstation为虚拟机所创建的那个目录中. 如下图所示:(< ...
- C++学习笔记 之 运算符
用来执行特定的数字或逻辑操作,C++主要提供的运算符如下: 算数运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 杂项运算符 算数运算符: 主要运算符:+(加).-(减) .*(乘) ./(除) ...
- 谈谈NOSQL
从MongoDB引到NOSQL 要讲MongoDB之前,首先要提到一个概念NOSQL(NoSQL = Not Only SQL ) 很大一部分数据是由关系型数据库管理系统(RDMBSs)来处理的,关系 ...
- Appium+python自动化(十五)- Android 这些基础知识,你知多少???(超详解)
简介 前边具体操作和实战已经讲解和分享了很多了,但是一些android的一些基础知识,你又知道多少了,你都掌握了吗?这篇就由宏哥给小伙伴们既是一个分享,又是对前边的一次总结.为什么要对这些做一个简单的 ...
- POJ 1741:Tree(树上点分治)
题目链接 题意 给一棵边带权树,问两点之间的距离小于等于K的点对有多少个. 思路 <分治算法在树的路径问题中的应用> 图片转载于http://www.cnblogs.com/Paul-Gu ...