认真学习设计模式之工厂模式(Factory Pattern)

简介: 认真学习设计模式之工厂模式(Factory Pattern)

在设计模式中,所谓的“实现一个接口”并“不一定”表示“写一个类,并利用implement关键字实现某个Java接口”。“实现一个接口”泛指“实现某个超类型(可以是类或接口)的某个方法”。


工厂模式的意义是将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦。从而提高项目的扩展和维护性。


三种工厂模式(简单工厂模式、工厂方法模式、抽象工厂模式)

【1】简单工厂/静态工厂

简单工厂其实不是一个设计模式,反而比较像是一种编程习惯,使用一个工厂类的静态方法来获取具体的"产品"实例

public class PizzaStore{
  public orderPizza(){
    //使用工厂类的静态方法获取Pizza实例
    Pizza a1=SimplePizzaFactory.createPizza();
    //...
  }
}
//工厂类
public class SimplePizzaFactory{
  //工厂类的静态方法
   public static Pizza createPizza(){
    //...
    return new CheesePizza();
  }
}
public abstract class Pizza {
    abstract  void  prepare();
    //...
}


实例uml图如下(核心思想就是将创建实例的地方交给工厂来做):



简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式。

简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为(代码)


在软件开发中,当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式。


【2】工厂方法模式

① 工厂方法模式


工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个,工厂方法让类把实例化推迟到子类。也就是一个抽象类里面有一个抽象方法,该方法用来生产产品,该抽象方法就是工厂方法。


工厂方法模式能够封装具体类型的实例化。看下面的类图,抽象的Creator提供了一个创建对象的方法的接口,也称为“工厂方法”。在抽象的Creator中,任何其他实现的方法,都可能使用到这个工厂方法所制造出来的产品,但只有子类真正实现这个工厂方法并创建产品。


这里需要注意的是,“工厂方法让子类决定要实例化的类是哪一个”。希望不要理解错误,所谓的“决定”,并不是指模式允许子类本身在运行时做决定,而是指在编写创建者类时,不需要知道实际创建的产品是哪一个。选择了使用哪个子类,自然就决定了实际创建的产品是什么。


20190222153237908.png


② 工厂方法

工厂方法用来处理对象的创建,并将这样的行为封装在子类中。这样客户程序中关于超类的代码就和子类对象创建代码解耦了



工厂方法是抽象的,所以依赖子类来处理对象的创建;

工厂方法必须返回一个产品。超类中定义的方法,通常使用到工厂方法的返回值。

工厂 方法将客户和实际创建具体产品的代码分隔开来;

工厂方法可能需要参数(也可能不需要)来指定所要的产品。

所有工厂模式都用来封装对象的创建。工厂方法模式(Factory Method Pattern)通过让子类决定该创建的对象是什么,来达到将对象创建的过程封装的目的。

工厂方法模式的组成元素



③ 工厂方法与简单工厂

简单工厂把全部的事情,在一个地方都处理完了。然而工厂方法却是创建一个框架,让子类决定如何实现。简单工厂的做法,可以将对象的创建封装起来,但是简单工厂不具备工厂方法的弹性,因为简单工厂不能变更正在创建的产品。


“工厂带来的好处”

将创建对象的代码几种在一个对象或方法中,可以避免代码中的重复,并且更方便以后的维护。这也意味着客户在实例化对象时,只会依赖于接口,而不是具体类。这可以帮助程序员“针对接口编程,而不针对实现编程”,这让代码更具有弹性,可以应对未来的扩展。



④ 依赖倒置原则



这里还涉及到一个设计原则“依赖倒置原则”。“要依赖抽象,不要依赖具体类”。这里更强调“抽象”,这个原则说明了:不能让高层组件依赖底层组件,而且,不管高层或底层组件,“两者”都应该依赖于抽象。


所谓“高层”组件 ,是由其他底层组件定义其行为的类。例如PizzaStore是个高层组件,因为它的行为是由比萨定义的:PizzaStore创建所有不同的比萨对象,准备、烘烤、切片、装盒;而比萨本身属于底层组件。

几个指导方针,帮助编码在OO设计中违反依赖倒置原则:


  • 变量不可以持有具体类的引用;
  • 不要让类派生自具体类;
  • 不要覆盖基类中已实现的方法。

实际中,要完全遵守这些指导方针似乎不太可能,但是应该尽量达到这个原则,而不是随时都要遵循这个原则。


⑤ 工厂方法实例

//接口的应用:工厂方法的设计模式
public class TestFactoryMethod {
  public static void main(String[] args) {
    IWorkFactory i = new StudentWorkFactory();
    i.getWork().doWork();
    IWorkFactory i1 = new TeacherWorkFactory();
    i1.getWork().doWork();
  }
}
//接口定义一个工厂方法用来生产产品
interface IWorkFactory{
  Work getWork();
}
//子类实现工厂方法创建产品
class StudentWorkFactory implements IWorkFactory{
  public Work getWork() {
    return new StudentWork();
  }
}
//子类实现工厂方法创建产品
class TeacherWorkFactory implements IWorkFactory{
  public Work getWork() {
    return new TeacherWork();
  }
}
interface Work{
  void doWork();
}
class StudentWork implements Work{
  public void doWork() {
    System.out.println("学生写作业");
  }
}
class TeacherWork implements Work{
  public void doWork() {
    System.out.println("老师批改作业");
  }
}


【3】抽象工厂模式


抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。抽象工厂允许客户使用抽象的接口来创建一组相关的产品,而不需要知道(或关心)实际产出的具体产品是什么。这样一来,客户就从具体的产品中被解耦。


抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合。从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)。


将工厂抽象成两层,AbsFactory(抽象工厂) 和具体实现的工厂子类。程序员可以根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。

UML类图



工厂方法和抽象工厂


抽象工厂的方法经常以工厂方法的方式实现。抽象工厂的任务是定义一个负责创建一组产品的接口。这个接口内的每个方法都负责创建一个具体产品,同时我们利用实现抽象工厂的子类来提供这些具体的做法。


抽象工厂与工厂方法都是负责创建对象,不同的是工厂方法是通过继承实现的,而抽象工厂是通过对象的组合实现的。这意味着利用工厂方法创建对象,需要扩展一个类并覆盖它的工厂方法。


其实整个工厂方法模式,只不过就是通过子类来创建对象。用这种做法,客户只需要知道他们所使用的抽象类型就可以了,而由子类来负责决定具体类型。换句话说,工厂方法只负责将客户从具体类型中解耦。


其实整个工厂方法模式,只不过就是通过子类来创建对象。用这种做法,客户只需要知道他们所使用的抽象类型就可以了,而由子类来负责决定具体类型。抽象工厂提供了一个用来创建一个产品家族的抽象类型,这个类型的子类定义了产品被产生的方法。要想使用这个工厂,必须先实例化它,然后将它传入一些针对抽象类型所写的代码中。所以和工厂方法意义,抽象工厂可以把客户从所使用的实际具体产品中解耦。抽象工厂的另一个优点是可以把一群相关的产品集合起来。


工厂方法使用的是类,而抽象工厂使用的是对象

工厂方法使用继承,而抽象工厂使用对象的组合

抽象工厂可以把一群相关的产品集合起来;

工厂方法允许类将实例化延迟到子类进行;

抽象工厂创建相关的对象家族,而不需要依赖他们的具体类;;

所有的工程模式都通过减少应用程序和具体类之间的依赖促进松耦合。

使用场景

当你需要创建产品家族和想让制造的相关产品集合起来时,可以使用抽象工厂。

工厂方法可以把客户代码从需要实例化的具体类中解耦。或者如果你目前还不知道将来需要实例化哪些具体类时,也可以用工厂方法。只要把工厂方法继承成子类并实现工厂方法就可。

目录
相关文章
|
1月前
|
设计模式 Java
【设计模式】工厂模式(定义 | 特点 | Demo入门讲解)
【设计模式】工厂模式(定义 | 特点 | Demo入门讲解)
54 2
|
2月前
|
设计模式
设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)
这篇文章详细解释了工厂模式,包括简单工厂、工厂方法和抽象工厂三种类型。每种模式都通过代码示例展示了其应用场景和实现方法,并比较了它们之间的差异。简单工厂模式通过一个工厂类来创建各种产品;工厂方法模式通过定义一个创建对象的接口,由子类决定实例化哪个类;抽象工厂模式提供一个创建相关或依赖对象家族的接口,而不需要明确指定具体类。
设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)
|
2月前
|
设计模式 Java
设计模式--适配器模式 Adapter Pattern
这篇文章介绍了适配器模式,包括其基本介绍、工作原理以及类适配器模式、对象适配器模式和接口适配器模式三种实现方式。
|
3月前
|
设计模式 Java
Java 设计模式之谜:工厂模式与抽象工厂模式究竟隐藏着怎样的神奇力量?
【8月更文挑战第30天】在Java编程中,设计模式为常见问题提供了高效解决方案。工厂模式与抽象工厂模式是常用的对象创建型设计模式,能显著提升代码的灵活性、可维护性和可扩展性。工厂模式通过定义创建对象的接口让子类决定实例化哪个类;而抽象工厂模式则进一步提供了一个创建一系列相关或相互依赖对象的接口,无需指定具体类。这种方式使得系统更易于扩展和维护。
42 1
|
3月前
|
设计模式 算法 开发者
深入理解工厂模式与策略模式:设计模式的灵活应用
深入理解工厂模式与策略模式:设计模式的灵活应用
|
3月前
|
设计模式 uml C语言
设计模式----------工厂模式之简单工厂模式(创建型)
这篇文章详细介绍了简单工厂模式,包括其定义、应用场景、UML类图、通用代码实现、运行结果、实际应用例子,以及如何通过反射机制实现对象创建,从而提高代码的扩展性和维护性。
设计模式----------工厂模式之简单工厂模式(创建型)
|
3月前
|
设计模式 Java C语言
设计模式-----------工厂模式之抽象工厂模式(创建型)
抽象工厂模式是一种创建型设计模式,它提供了一个接口用于创建一系列相关或相互依赖的对象,而无需指定具体类,从而增强了程序的可扩展性并确保客户端只使用同一产品族的产品。
设计模式-----------工厂模式之抽象工厂模式(创建型)
|
21天前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
2月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
24天前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###