【GOF】三种工厂模式~
@[toc]
工厂模式
作用:实现了创建者和调用者的分离
详细分类:
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
1 简单工厂模式
1.1 什么是简单工厂模式
简单工厂模式是属于创建型模式,又叫做静态工厂方法模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。在开发过程中非常实用。
简单工厂可以根据传入的参数不同,返回不同类的实例
简单工厂模式中,简单工厂类负责创建其他类的实例,其他类通常都具有共同的父类
1.2 使用简单工厂模式与不使用简单工厂的对比
1.2.1 不使用简单工厂模式
不使用简单工厂模式,用户需要自己new 所需要的实例,比如想要使用Tesla的属性,就必须得先创建(new)Tesla类,然后才可以使用Tesla属性。这意味着你需要了解一下实现类的内部(比如需不需要传参),如果用到的次数非常的对,就需要实例化很多次。
1.2.2 使用简单工厂模式
使用简单工厂模式,就不需要每次都实例化,只需要直接使用工厂的方法获取实例即可(简单工厂的方法是静态的,不需要new简单工厂,这也是为什么简单工厂模式又叫静态工厂方法)
1.3 简单工厂的例子
Car.interface
public interface Car {
void name();
void price();
}
Tesla.java
public class Tesla implements Car{
@Override
public void name() {
System.out.println("特斯拉汽车");
}
@Override
public void price() {
System.out.println("¥500000");
}
}
Wuling.java
public class WuLing implements Car{
@Override
public void name() {
System.out.println("五菱宏光");
}
@Override
public void price() {
System.out.println("¥9999999");
}
}
CarFactory.java
public class CarFactory {
/* 生产五菱宏光 */
public static WuLing productWuling()
{
return new WuLing();
}
/* 生产特斯拉 */
public static Tesla productTesla()
{
return new Tesla();
}
}
Customer.java
public class Customer {
public static void main(String[] args) {
Tesla tesla = CarFactory.productTesla();
tesla.name();
tesla.price();
}
}
1.4 简单工厂的缺点
如果再增加一个车,就必须要改变CatFactory类,这违法了开闭原则。
所以,简单工厂模式对于产品角色的开-闭原则是成立的,对于工厂角色开-闭原则则是不成立的。简单工厂角色只在有限的程度上支持开闭原则。
2 工厂方法模式
2.1 简介
工厂方法模式是一种常用的类创建型设计模式,此模式的核心精神是封装类中变化的部分,提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦、复用和方便后期维护拓展的目的。它的核心结构有四个角色,分别是抽象工厂、具体工厂、抽象产品、具体产品。
工厂方法模式对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不再负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。
2.2 例子
工厂方法模式对简单工厂模式做了一些改进,让简单工厂模式能够完全遵循开闭原则。
对1.3例子的优化
在1.3的基础上,将CarFactory分离出来,不是有一个大的工厂,而是每种汽车都有自己的工厂,生产产品,而每个汽车工厂遵循一定的规范。
简单工厂
工厂方法模式
Factory.interface
public interface Factory {
public Car productCar();
}
TeslaFactory.java
public class TeslaFactory implements Factory{
@Override
public Car productCar() {
return new Tesla();
}
}
WulingFactory.java
public class WulingFactory implements Factory{
@Override
public Car productCar() {
return new WuLing();
}
}
这样Customer可以直接通过品牌汽车工厂生产相应品牌的汽车
Customer.java
public class Customer {
public static void main(String[] args) {
Car car = new TeslaFactory().productCar();
car.name();
}
}
2.2.1 增加新品牌的汽车
这时候便不需要改动工厂Factory,只需要增加一个新的汽车工厂类DazongFactory和汽车类 Dazong
DaZongFactory.java
public class DaZongFactory implements Factory{
@Override
public Car productCar() {
return new DaZong();
}
}
DaZong.java
public class DaZong implements Car{
@Override
public void name() {
System.out.println("大众汽车..");
}
@Override
public void price() {
System.out.println("¥88888888");
}
}
2.3 类图
懒得画了,自动生成的,反正是增加汽车不会改变原有的代码和结构,没有违法开闭原则
2.4 注意
但是在实际开发过程中,简单工厂模式用的更多,因为工厂方法模式虽然很好的保证了开闭原则,但是实现起来也复杂的多,所以我们基本上都使用简单工厂模式。
3 抽象工厂模式
3.1 概念
抽象工厂模式(Abstract Factory Pattern)隶属于设计模式中的创建型模式,用于产品族的构建。抽象工厂是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂是指当有多个抽象角色时使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象。
抽象工厂模式提供了一个创建一系列相关或者相互依赖对象的接口,无需指定它们具体的类
产品族::在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。如华为工厂可以生产华为产品包括:华为手机、华为路由器、华为电视
产品等级结构:产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有华为电视机、小米电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。
注意:横纵坐标的意思是,每一列的继承结构是产品等级结构,每一行代表的是一个产品族。
3.2 例子
针对上图,设计一个抽象工厂模式。
有三个产品等级结构:手机、电视、路由器
有三个产品族:华为、小米、TCL
为了简化操作每个产品只有打开和关闭两个功能。(emm…还是太多了,只写手机和电视)
类非常的多,但使用起来,感觉很不错
Factory.interface
public interface Factory {
public PhoneProduct productPhone();
public TvProduct productTV();
}
产品族 就体现在以下的代码中,每个品牌的工厂可以生产自己品牌的所有产品
HuaweiFactory.java
public class HuaweiFactory implements Factory{
@Override
public PhoneProduct productPhone() {
return new HuaWeiPhone();
}
@Override
public TvProduct productTV() {
return new HuaweiTv();
}
}
XiaomiFactory.java
public class XiaomiFactory implements Factory{
@Override
public PhoneProduct productPhone() {
return new XiaomiPhone();
}
@Override
public TvProduct productTV() {
return new XiaomiTv();
}
}
TclFactory.java
public class TclFactory implements Factory{
@Override
public PhoneProduct productPhone() {
return new TclPhone();
}
@Override
public TvProduct productTV() {
return new TclTv();
}
}
PhoneProduct.interface
public interface PhoneProduct {
public void open();
public void close();
}
XiaomiPhone.java
public class XiaomiPhone implements PhoneProduct{
@Override
public void open() {
System.out.println("打开小米手机.....");
}
@Override
public void close() {
System.out.println("关闭小米手机........");
}
}
HuaWeiPhone.java
public class HuaWeiPhone implements PhoneProduct{
@Override
public void open() {
System.out.println("打开华为手机.....");
}
@Override
public void close() {
System.out.println("关闭华为手机.....");
}
}
TclPhone.java
public class TclPhone implements PhoneProduct{
@Override
public void open() {
System.out.println("打开TCL手机");
}
@Override
public void close() {
System.out.println("关闭Tcl手机");
}
}
上面这四个就体现了产品等级机构
其他的就是照猫画虎…实在太多 不写了
Client.java
public class Client {
public static void main(String[] args) {
PhoneProduct phoneProduct = new HuaweiFactory().productPhone();
phoneProduct.open();
phoneProduct.close();
}
}
3.3 适用场景
-
客户端(应用层)不依赖产品类实例如何被创建、实现等细节
-
强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复代码
-
提供一个产品类的库,所有的产品以同样的接口出现,从而使得客户端不依赖于具体的实现
3.4 优缺点
优点:
- 具体产品在应用层的代码隔离,无需关心创建的细节
- 将一个系列的产品统一到一起创建
缺点
- 规定了所有可能被创建的产品集合,产品族中拓展新的产品困难。
- 增加了系统的抽象性和理解难度。
- 点赞
- 收藏
- 关注作者
评论(0)