工厂模式(简单工厂、工厂方法、抽象工厂)
简单工厂模式
从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(StaticFactory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
简单工厂模式的一般结构,如图所示:
上门2个图片有对简单工厂模式的理解,来源《java与模式》
使用场景
工厂类负责创建的对象比较少。
客户端只知道传入工厂类的参数,对于如何创建对象并不关心。
l 工厂角色
l 抽象产品角色
l 具体产品角色
其实角色这个词用的比较确切,能够让我们理解到,每个角色的不是单纯地指一个类,可能是一组类所构成了这个角色。下面对三个角色进行描述:
1. 工厂角色
工厂角色负责产品的生产工作。在简单工厂模式中,工厂类是一个具体的实现类,在系统设计中工厂类负责实际对象的创建工作。
工厂类(Factory)的特点是:它知道系统中都存在哪些能够创建对象的具体类(ConcreteProduct),也知道该如何将创建的对象,以某种能够屏蔽具体类实现细节的方式(AbstractProduct)提供给所需要的其他角色来使用该对象提供的数据和服务。
2.抽象产品角色
抽象产品角色是具体的产品的抽象。抽象就是将产品的共性抽取出来,可以直接暴露给客户端(需要使用具体产品的角色),对所有的客户端来说,从工厂中直接获取到的原始产品的外部形态都是相同的,没有任何的差别,包括数据和服务。这也就是说,具体客户端应该“秘密”掌握着某一个或一些具体产品的详细资料(具体产品类型、数据和服务),然后根据具体客户端(任何一个需要使用某种具体产品的数据和服务的实现类)需要什么样的附加数据和服务,进行类类型转换后,通过借助于对应的具体产品对象来完成其职责。
抽象产品角色,在实际系统中可以定义为接口或者抽象类。
3.具体产品角色
具体产品实现类一定是抽象产品类的实现或扩展。为了保证工厂类能够创建对象,工厂类需要知道具体产品的创建方式,这就涉及到具体产品类所提供的构造方法,以便,可能工厂类会向客户端提供具体创建服务所需要的数据。例如:某个产品类需要通过一个账号才能构造其实例,所以工厂类必须根据它的创建需求,为客户端提供一个带账号参数的生产方法,才能创建该具体产品类的对象。
也就是说,工厂类依赖于具体产品实现类。同样,客户端类是依赖于工厂类的。
通过上述三个角色的描述,我们应该能够了解,系统中哪些类能够胜任上述的三个角色,并通过各类之间的关系,通过工厂模式来实现系统或者某个模块。在实际的设计过程中,可能不存在完全与上述基本简单工厂模式完全适应的,需要根据具体的需求来调整简单工厂模式的应用。只要能够实现系统的良好设计,有时候变化才能满足需要。
下面用一个简单的例子来说明一下,给大家加深一下印象(例子来自于网络):
运动员.java
public interface 运动员 { public void 跑();public void 跳();
}
足球运动员.java
public class 足球运动员 implements 运动员 {public void 跑(){//跑啊跑} public void 跳(){//跳啊跳}
}
篮球运动员.java
public class 篮球运动员 implements 运动员 {public void 跑(){//do nothing} public void 跳(){//do nothing}
}
体育协会.java
public class 体育协会 { public static 运动员 注册足球运动员(){return new 足球运动员();} public static 运动员 注册篮球运动员(){return new 篮球运动员();}
}俱乐部.java
public class 俱乐部 {private 运动员 守门员;private 运动员 后卫;private 运动员 前锋;public void test() {this.前锋 = 体育协会.注册足球运动员();this.后卫 = 体育协会.注册足球运动员();this.守门员 = 体育协会.注册足球运动员();守门员.跑();后卫.跳();}
}
以上就是简单工厂模式的一个简单实例,读者应该想象不用接口不用工厂而把具体类暴露给客户端的那种混乱情形吧(就好像没了体育总局,各个俱乐部在市场上自己胡乱的寻找仔细需要的运动员),简单工厂就解决了这种混乱。
工厂方法模式
工厂方法模式是类的创建模式,又叫虚拟构造子(Virtual Constructor)模式或者多态性工厂(Polymorphic Factory)模式。 工厂方法模式的用意是定义一个创建产品对象的工厂接口,将实际工作推迟到子类中。
工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现‘开-闭 原则’,实现了可扩展。其次更复杂的层次结构,可以应用于产品结果复杂的场合。工厂方法模式的对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不在负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以依次对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。
工厂方法模式角色与结构
1.抽象工厂(Creator)角色:是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。
2.具体工厂(Concrete Creator)角色:这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。
3.抽象产品(Product)角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。
4.具体产品(Concrete Product)角色:这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应。
工厂方法模式的一般结构,如图所示:
我们在不改变产品类(“足球运动员”类和“篮球运动员”类)的情况下,写一下工厂方法模式的例子:
运动员.java
public interface 运动员 { public void 跑();public void 跳();
}足球运动员.java
public class 足球运动员 implements 运动员 {public void 跑(){//跑啊跑}public void 跳(){//跳啊跳}
}篮球运动员.java
public class 篮球运动员 implements 运动员 {public void 跑(){//do nothing}public void 跳(){//do nothing}
}体育协会.java
public interface 体育协会 {public 运动员 注册();
}足球协会.java
public class 足球协会 implements 体育协会 {public 运动员 注册(){return new 足球运动员();}
}篮球协会.java
public class 篮球协会 implements 体育协会 {public 运动员 注册(){return new 篮球运动员();}
}俱乐部.java
public class 俱乐部 {private 运动员 守门员;private 运动员 后卫;private 运动员 前锋;public void test() {体育协会 中国足协 = new 足球协会();this.前锋 = 中国足协.注册();this.后卫 = 中国足协.注册();守门员.跑();后卫.跳();}
}
很明显可以看到,“体育协会”工厂类变成了“体育协会”接口,而实现此接口的分别是“足球协会”“篮球协会”等等具体的工厂类。
这样做有什么好处呢?很明显,这样做就完全OCP了。如果需要再加入(或扩展)产品类(比如加多个“乒乓球运动员”)的话就不再需要修改工厂类了,而只需相应的再添加一个实现了工厂接口(“体育协会”接口)的具体工厂类。
抽象工厂模式
抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。根据LSP原则,任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。换言之,也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。
先来认识下什么是产品族: 位于不同产品等级结构中,功能相关联的产品组成的家族。还是让我们用一个例子来形象地说明一下吧。
抽象工厂模式中的有以下的四种角色:
抽象工厂(Abstract Factory)角色:担任这个角色的是工厂方法模式的核心,它是与应用系统商业逻辑无关的。
具体工厂(Concrete Factory)角色:这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。
抽象产品(Abstract Product)角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。
具体产品(Concrete Product)角色:这个角色用以代表具体的产品。
Abstract Factory模式的结构:
package abstractFactory;public interface KitchenFactory{public Food getFood();public TableWare getTableWare();}抽象餐具的接口定义如下所示:package abstractFactory;public interface TableWare{public String getTool();}抽象事物的接口定义如下所示:package abstractFactory;public interface Food{public String getEatable();}而具体的实现也非常简单,以AKitchen为例子具体工厂AKitchen的定义如下所示;package abstractFactory;public class AKitchenimplements KitchenFactory{public Food getFood(){return new Milk();}public TableWare getTableWare(){return new Spoon();}}具体餐具(spoon)的定义如下所示:package abstractFactory;public class Spoonimplements TableWare{ public String getTool() {return "spoon";}}具体食物(milk)的定义如下所示:package abstractFactory;public class Milkimplements Food{public String getEatable(){return "milk";}}客户端的定义如下:package abstractFactory;public class Client{public void eat(KitchenFactory k){System.out.println("A person eat "+k.getFood().getEatable()+" with "+k.getTableWare().getTool()+"!");}public static void main(String[] args){Client client=new Client();KitchenFactory kf =new AKitchen();client.eat(kf);kf=new BKitchen();client.eat(kf);kf=new CKitchen();client.eat(kf);}}
在以下情况下应当考虑使用抽象工厂模式:
· 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。
· 这个系统有多于一个的产品族,而系统只消费其中某一产品族。
· 同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。
· 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。
工厂模式(简单工厂、工厂方法、抽象工厂)相关推荐
- 工厂模式详解(简单工厂模式,工厂方法模式,抽象工厂模式,只给出抽象工厂模式具体代码)
1.简单工厂模式(Factory) 应用场景:又叫做静态工厂方法(StaticFactory Method)模式,但不属于 23 种设计模式之一.简单工厂模式的实质是由一个工厂类根据传入的参数,动态决 ...
- 抽象工厂模式(三):抽象工厂模式概述
3 抽象工厂模式概述 抽象工厂模式为创建一组对象提供了一种解决方案.与工厂方法模式相比,抽象工厂模式中的具体工厂不只是创建一种产品,它负责创建一族产品.抽象工厂模式定义如下: 抽象工厂模 ...
- 【怎样写代码】工厂三兄弟之抽象工厂模式(四):抽象工厂模式
如果喜欢这里的内容,你能够给我最大的帮助就是转发,告诉你的朋友,鼓励他们一起来学习. If you like the content here, you can give me the greates ...
- 工厂模式(简单工厂 工厂方法 抽象工厂)
简单工厂模式 简单工厂模式又叫做静态工厂方法模式(static Factory Method pattern),它是通过使用静态方法接收不同的参数来返回不同的实例对象(这些产品类继承自一个父类或接口) ...
- 创建型模式:工厂模式(简单工厂+工厂方法+抽象工厂)
一.引子 话说十年前,有一个爆发户,他家有三辆汽车(Benz(奔驰).Bmw(宝马).Audi(奥迪)),还雇了司机为他开车.不过,爆发户坐车时总是这样:上Benz车后跟司机说"开奔驰车!& ...
- java 三种工厂模式(简单工厂+工厂方法+抽象工厂)
一.简单工厂模式 概述 简单工厂模式:定义一个工厂类,它可以根据参数的不同返回不同类的 实例,被创建的实例通常都具有共同的父类.因为在简单工厂模式中用于创建实例的方法是静态(static)方法,因 ...
- 最简单java设计模式:抽象工厂模式
前言 在前一篇文章讲解了一下简单工厂模式和工厂方法模式,这篇文章再把抽象工厂模式讲解一下. 一.什么是抽象工厂模式 抽象工厂模式是所有形态的工厂模式中最为抽象和最其一般性的.抽象工厂模式可以向客户端提 ...
- java 抽象工厂模式简单实例
抽象工厂模式:提供一个创建一系列的相关的或者依赖的对象的接口,无需指定它们的具体实现类,具体的时间分别在子类工厂中产生. 类似于工厂模式:隔离了具体类的生产实现,使得替换具体的工厂实现类很容易.包含有 ...
- 工厂模式,简单工厂模式,抽象工厂模式三者有什么区别
工厂模式,也叫做说虚构造器,在简单工厂中间插入了一个具体产品工厂,这个工厂知道产品构造时候的具体细节,而简单工厂模式的产品具体构造细节是在一个个if/else分支,或者在switch/case分支里面 ...
- 工厂模式--简单工厂模式--抽象工厂模式
工厂模式 作用:实现创建者与调用者的分离 简单工厂模式.工厂方法模式.抽象工厂模式,都是属于创建型设计模式.严格上来说,简单工厂模式不属于23设计模式之一,因为它违背了开闭原则. ========== ...
最新文章
- Kotlin——初级篇(六):空类型、空安全、非空断言、类型转换等特性总结
- 斐波那契博弈(证明+结论)
- 23种设计模式之原型模式代码实例
- Cocos2d-x for Android iOS开发环境配置最佳实践
- poi 获取删除线_Houdini 删除相机看不到的点背面的点或面
- Visual Studio安装教程
- 使用HTML实现百度首页界面
- imagine php,Yii2第三方类库插件Imagine的安装和使用
- 为什么别人的移动开发效率是你的2倍?丨课程推广
- 爱情、面包论——真正的爱情
- 分布式与容器化的介绍
- c语言自动售货机实验报告,c语言自动售货机实验报告(15页)-原创力文档
- 汇编-ARMv8架构指令集
- 5S现场管理法(转载)
- python时间差计算器时分秒_python 实现日期计算器
- hihocoder1636-Pangu and Stones
- MySQL 到Oracle 实时数据同步实操分享
- 多项式拟合忆阻器的相关数据,超详细解决忆阻器数据的拟合问题(还有很大改进空间)
- 32.深度解密三十二:详解影响QQ群整体排名的那些秘密
- go kratos 学习笔记(三)
热门文章
- .NET Worker Service 作为 Windows 服务运行及优雅退出改进
- 记一次 .NET医疗布草API程序 内存暴涨分析
- 如何在 C# 中使用匿名类型
- 如何在.NET应用程序中分析CPU使用率过高的问题
- 这些年我对微服务的理解
- 一文读懂开源许可证异同
- 如何为.NETCore安装汉化包智能感知
- NETCore Bootstrap Admin 通用后台管理权限 [1]: 前后台分离系统简介
- .NET Core 如何判断程序是否在远程桌面(RDP)下运行
- 告别2019,写给2020:干好技术,要把握好时光里的每一步