针对Java设计模式,推荐一书《大话设计模式》:
链接: https://pan.baidu.com/s/16YZ8nMx6M2C94_dmMWjh0w 提取码: aw5y
Factory工厂模式分为:
1)简单工厂模式(Simple Factory) --- 普通工厂模式
2)工厂方法模式(Factory Method) --- 多工厂模式
3)抽象工厂模式(Abstract Factory) --- 抽象工厂模式
什么时候需要用工厂模式呢?
工厂,从字面意思理解,就是造东西的地方。所以,需要很多类型或者经常升级换代,就可以使用工厂模式。比如,宝马工厂,它有很多产品,而且每一款产品还时不时地升个级,换个代,所以就有工厂这个东西。
所以,使用工厂模式,你需要确定一点:
工厂模式针对的是多态。也就是说,你的类型如果可能有很多派生,使用工厂模式比较方便。
如果你的需求是经常会添加的,比如会添加某个方法,那么使用工厂模式反而很麻烦,因为你要修改一连串的项目文件
所以,工厂模式的适用场景大致有这些:
1)对象的创建过程(实例化)很复杂,需要初始化很多参数,比如查询数据库等。
2)类本身有好多子类,这些类的创建过程在业务中容易发生改变,或者对类的调用容易发生改变。
工厂模式的优点
1)解耦:把对象的创建和使用的过程分开
ClassA想调用ClassB(其实只是想调用B的方法)不再需要New一个B,B的实例化,就交给工厂类。
2)统一管理对象的创建过程,降低代码重复
如果很多地方都需要创建对象B(创建过程复杂),那么很多地方都需要New B(),此时代码重复就比较多。
如果把创建对象B的代码放到工厂里统一管理,既减少了重复代码,也方便以后对B的创建过程的修改维护。
中国有16亿人,如果每人想买一辆宝马,只需要告诉工厂,你想买什么类型的宝马,是宝马320还是宝马523……工厂直接生产出来给你就好了,这就是通俗理解工厂模式!通俗理解其好处就是:方便更改应用程序和扩展。
工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。
也有的人将简单工厂模式看为工厂方法模式的一种特例,两者归为一类。所以实际分为两类:工厂方法模式与抽象工厂模式,两者区别如下:
(1)工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个抽象产品类。
(2)工厂方法模式只有一个抽象工厂类,而抽象工厂模式有多个抽象工厂类。
(3)工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个具体产品类的实例。
public class BMW320 {
public BMW320(){
System.out.println("制造-->BMW320");
}
}
public class BMW523 {
public BMW523(){
System.out.println("制造-->BMW523");
}
}
public class Customer {
public static void main(String[] args) {
BMW320 bmw320 = new BMW320();
BMW523 bmw523 = new BMW523();
}
}
这个例子,客户必须要知道怎么去创建一款车才可以,这样的话,客户和车就紧密耦合在一起了。为了降低耦合,就出现了工厂类,把创建宝马的操作细节都放到了工厂里面去,客户直接使用工厂的创建工厂方法,传入想要的宝马车型号就行了,而不必去知道创建的细节,这就是简单工厂模式了!
即我们建立一个工厂类方法来制造新的对象,如图:
// 产品类
abstract class BMW {
public BMW(){
}
}
public class BMW320 extends BMW {
public BMW320() {
System.out.println("制造-->BMW320");
}
}
public class BMW523 extends BMW{
public BMW523(){
System.out.println("制造-->BMW523");
}
}
// 工厂类
public class Factory {
public BMW createBMW(int type) {
switch (type) {
case 320:
return new BMW320();
case 523:
return new BMW523();
default:
break;
}
return null;
}
}
// 客户类
public class Customer {
public static void main(String[] args) {
Factory factory = new Factory();
BMW bmw320 = factory.createBMW(320);
BMW bmw523 = factory.createBMW(523);
}
}
简单工厂模式又称静态工厂方法模式,它存在的目的很简单:定义一个用于创建对象的接口。 先来看看它的组成:
- 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑,用来创建产品
- 抽象产品角色:它一般是具体产品继承的父类或者实现的接口
- 具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。
好了,现在假若客户想要增加车型,比如奔驰、保时捷……那么,就需要在工厂类中增加相应的创建业务逻辑,如果需要增加大量车型,那就得吐血了,所以,就出现了工厂方法模式 。
------- 工厂方法模式 ---------
工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得它可以被子类继承,这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。
工厂方法模式组成:
1)抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
2)具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
3)抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
4)具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
看如下代码:
// 产品类
abstract class BMW {
public BMW(){
}
}
public class BMW320 extends BMW {
public BMW320() {
System.out.println("制造-->BMW320");
}
}
public class BMW523 extends BMW{
public BMW523(){
System.out.println("制造-->BMW523");
}
}
// 工厂类
interface FactoryBMW {
BMW createBMW();
}
public class FactoryBMW320 implements FactoryBMW{
@Override
public BMW320 createBMW() {
return new BMW320();
}
}
public class FactoryBMW523 implements FactoryBMW {
@Override
public BMW523 createBMW() {
return new BMW523();
}
}
// 客户类
public class Customer {
public static void main(String[] args) {
FactoryBMW320 factoryBMW320 = new FactoryBMW320();
BMW320 bmw320 = factoryBMW320.createBMW();
FactoryBMW523 factoryBMW523 = new FactoryBMW523();
BMW523 bmw523 = factoryBMW523.createBMW();
}
}
工厂方法模式仿佛已经很完美的对对象的创建进行了包装,使得客户程序中仅仅处理抽象产品角色提供的接口,但这样会使得对象的数量成倍增长。当产品种类非常多时,会出现大量的与之对应的工厂对象,所以就出现抽象工厂模式了。
---------- 抽象工厂模式 ---------
随着客户的要求越来越高,宝马车需要不同配置的空调和发动机等配件。于是这个工厂开始生产空调和发动机,用来组装汽车。这时候工厂有两个系列的产品:空调和发动机。宝马320系列配置A型号空调和A型号发动机,宝马230系列配置B型号空调和B型号发动机。
抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象,代码:
// 产品类
//发动机以及型号
public interface Engine {
}
public class EngineA extends Engine{
public EngineA(){
System.out.println("制造-->EngineA");
}
}
public class EngineBextends Engine{
public EngineB(){
System.out.println("制造-->EngineB");
}
}
//空调以及型号
public interface Aircondition {
}
public class AirconditionA extends Aircondition{
public AirconditionA(){
System.out.println("制造-->AirconditionA");
}
}
public class AirconditionB extends Aircondition{
public AirconditionB(){
System.out.println("制造-->AirconditionB");
}
}
// 工厂类
//创建工厂的接口
public interface AbstractFactory {
//制造发动机
public Engine createEngine();
//制造空调
public Aircondition createAircondition();
}
//为宝马320系列生产配件
public class FactoryBMW320 implements AbstractFactory{
@Override
public Engine createEngine() {
return new EngineA();
}
@Override
public Aircondition createAircondition() {
return new AirconditionA();
}
}
//宝马523系列
public class FactoryBMW523 implements AbstractFactory {
@Override
public Engine createEngine() {
return new EngineB();
}
@Override
public Aircondition createAircondition() {
return new AirconditionB();
}
}
// 客户类
public class Customer {
public static void main(String[] args){
//生产宝马320系列配件
FactoryBMW320 factoryBMW320 = new FactoryBMW320();
factoryBMW320.createEngine();
factoryBMW320.createAircondition();
//生产宝马523系列配件
FactoryBMW523 factoryBMW523 = new FactoryBMW523();
factoryBMW320.createEngine();
factoryBMW320.createAircondition();
}
}
抽象工厂模式和工厂方法模式的区别,仔细看代码就能体会。