0
点赞
收藏
分享

微信扫一扫

Java---23种设计模式(三)------抽象工厂


1.什么是抽象工厂与工厂方法的区别联系

抽象工厂模式的定义:为创建一组相关相互依赖对象提供一个接口,而且无需指定它们的具体类

对比一下工厂方法模式的定义:为某个对象提供一个接口,而且无需指定它们的具体类

 

抽象工厂模式包括的角色

(1)抽象产品类:为各种产品声明抽象接口抽象类

(2)具体产品类抽象产品类的实现类,为实现某个具体产品的对象

(3)抽象工厂类声明了一组(注意是一组,看了下面的例子就会明白和工厂方法模式的区别)用于创建一种产品(每一个方法对应一种产品)的方法。

(4)具体工厂类继承抽象工厂类,生成一组具体产品(注意是一组,这很重要)。
 

2.与工厂方法的区别

工厂方法模式:

(1)多个具体产品类都衍生自同一个接口或抽象类

(2)一个抽象工厂类,可以派生出多个具体工厂类

(3)并且每个具体工厂类只能创建一个具体产品类的实例

 

抽象工厂模式:

(1)多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。(不同点)

(2)一个抽象工厂类,可以派生出多个具体工厂类。(同工厂方法模式)

(3)并且每个具体工厂类可以创建多个具体产品类的实例。(不同点)

 

简单解释来讲

比如说鞋厂只能生产同一款鞋,而设想下一家代加工的鞋厂,里面可能既加工Adidas的鞋,同时还加工Nike的鞋,或者再想想,Nike和Adidas公司在生产鞋的同时,都还在生产衣服,那么,这种情况用工厂模式就不能做到了,因此产生了抽象工厂模式。 
抽象工厂模式的适用范围比工厂模式更加广泛,它与工厂模式最大的区别在于: 
工厂模式中一个工厂只能生产一种产品,而抽象工厂可以生产多个。
 

2.抽象工厂的使用场景

1.当一个系统要独立于他的产品创建,组合,和表示的时候时;

2.一个系统要由多个产品系列的中的一个来配置时候;

3.当你要强调一系列相关产品对象的设计以便来进行联合使用时候;

4.当你提供一个产品类库,而只想显示他们的接口而不是实现时候;

使用场景: 1、QQ 换皮肤,一整套一起换。 2、生成不同操作系统的程序。

注意事项:产品族难扩展,产品等级易扩展。

 

何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。

 

如何解决:在一个产品族里面,定义多个产品。

关键代码:在一个工厂里聚合多个同类产品

 

优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。

注意事项:产品族难扩展,产品等级易扩展。

 

 

白话文版本:

最大的好处便是易于交换产品系列,由于具体工厂类,在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同产品配置。

2、它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操作实例产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中

 

最典型的用法:

   项目使用的是MySQL数据,现在如果需要更换为Oracle数据,为了灵活更换数据库,如何设计程序呢

   接下来通过抽象工厂模式模仿数据访问程序

    抽象工厂模式实现:

  

3.抽象工厂的用法

 

构建数据库表的对应类,只声明,不做任何操作。

User类:

Java---23种设计模式(三)------抽象工厂_抽象工厂

 

为表创建相应的实现类:

IUser接口,用于客户端访问,解除与具体数据库访问的耦合:

 

Java---23种设计模式(三)------抽象工厂_mysql_02

 

MySQLUser类,用于访问MySQL的User表:

 

Java---23种设计模式(三)------抽象工厂_oracle_03

 

OracleUser类,用于访问Oracle的User表:

 

 

Java---23种设计模式(三)------抽象工厂_抽象工厂_04

 

 

接下来再让我们构建一个IFactory接口,定义一个访问User表对象和Type对象的抽象的工厂接口

Java---23种设计模式(三)------抽象工厂_mysql_05

 

 

 

MySQLFactory类,实现IFactory接口,实例化MySQLUser

 

Java---23种设计模式(三)------抽象工厂_mysql_06

 

 

OracleFactory类,实现IFactory接口,实例化OracleUser

 

Java---23种设计模式(三)------抽象工厂_mysql_07

 

 

客户端代码

 

 

Java---23种设计模式(三)------抽象工厂_oracle_08

只需确认实例化哪一个数据库访问对象给factory。

运行结果如下:

 

Java---23种设计模式(三)------抽象工厂_oracle_09

 

只需要更改IFactory factory = new MySQLFactory() 为IFactory factory = new OracleFactory() ,就实现了数据库访问的切换了。

有一个User类和User操作类的时候,是只需要工厂方法模式,但是现在显然你数据中有很多的表,而MySQL和Oracle有时两大不同的分类,所以解决这种涉及到多个产品系列的问题,就需要抽象工厂模式了。

4.抽象工厂的类图

Java---23种设计模式(三)------抽象工厂_抽象工厂_10

5.抽象工厂的优缺点:

优点:

易于交换产品系列,由于具体工厂类,在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。

2、它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。

缺点:

如果要增加一个项目表Project,那么就需要增加三个类,IProject,MySQLProject,OracleProject,还需要改动IFactory,MySQLFactory,OracleFactory才可以完全实现。这样是很糟糕的。

编程是门艺术,这样大批量的改动,显然是非常丑陋的做法。

解决方案:可以使用简单工厂来改进抽象工厂。去除IFactory、MySQLFactory、OracleFactory三个工厂类,用一个DataAcces类代替,用一个简单工厂模式来实现。具体实现代码省略,有兴趣的小伙伴可以自己实现。

 

6.抽象工厂与工厂模式代码级别对比

重构类图

 

举报

相关推荐

0 条评论