Java设计模式之工厂模式

简介:
工厂模式
背景:
一般在程序过程中,利用new来创建对象的时候,也就是在具体化一个类。我们一直所提倡的就是针对接口编程,这样就可以让程序不用依赖于具体类的实现,而在运行中动态的绑定来实现多态功能。如果代码是针对接口而写的,那么通过多态,它可以与任何新类实现该接口。但是倘若代码使用大量的具体类的时候,就不利于维护,一旦加入新的具体类的时候,就要修改代码。
一般创建新对象最简单的办法是使用new关键字和具体类。只有在某些场合下,倘若要根据具体的条件来创建不同的类,则此时就需要一个专门用于创建和维护对象的工厂。
工厂模式分为三类:
1)简单工厂模式(Simple Factory) :不利于产生系列产品,也就是不利于多种类型产品。它主要是在基类由一个对象变量负责实例化所有的具体类,而这些具体类都属于一个相同的类型。
2)工厂方法模式(Factory Method) :又称为多形性工厂。 它的定义为:定义了一个创建对象的接口或抽象类,但由子类来决定要实例化的类是哪一个。工厂方法让类把实例化推迟到了子类中 。它通过继承父类,在子类中决定创建哪些实例化类。它主要用在当一个类有多个子类,而每一个子类又同时有各自专属的子类,则此时就可以用。
3)抽象工厂模式(Abstract Factory) :又称 它的定义为:提供了一个借口,用于创建相关或依赖对象的家族,而不需要明确指定具体的类。 为工具箱,产生产品族,但不利于产生新的产品;
一 简单工厂模式
简单工厂模式又称静态工厂方法模式。它存在的目的很简单:定义一个用于创建对象的接口。

在简单工厂模式中,一个工厂类处于对产品类实例化调用的中心位置上,它决定哪一个产品类应当被实例化。

简单工厂模式主要就是在定义了一个工厂对象变量作为类的字段,来产生对象。

先来看看它的组成:
1) 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现。
2) 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。
3) 具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。
这三种模式从上到下逐步抽象,并且更具一般性。在简单工厂中,工厂是另一个类的成员变量。
具体说明
一个pizza店,可以根据客户的点单而生产不同的Pizza
生产pizza店:
package com.whut.singleton;

//简单工厂模式
public  class PizzaStore {

SimplePizzaFactory factory;
public PizzaStore(SimplePizzaFactory factory)
{
this.factory=factory;
}

public Pizza orderPizza(String type)
{
Pizza pizza;
//只能创建某一个类型下的子类
pizza=factory.createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
创建Pizza对象的工厂:
package com.whut.singleton;

import com.whut.factory.NYStyleCheesePizza;
import com.whut.factory.NYStyleClamPizza;
import com.whut.factory.NYStyleVeggiePizza;
import com.whut.factory.Pizza;

public  class SimplePizzaFactory {

public Pizza createPizza(String item)
{
Pizza pizza= null;
// TODO Auto-generated method stub
if(item.equals( "cheese"))
pizza=  new NYStyleCheesePizza();
else if(item.equals( "veggie"))
pizza=  new NYStyleVeggiePizza();
else
pizza=  new NYStyleClamPizza();
return pizza;
}

}
二 工厂方法模式
工厂方法让子类决定要实例化的是哪个类,这里的决定并不是让类在运行时决定,而是在编写创建者类的时候,不需要知道实际创建的是哪一个产品。工厂方法其实就是在抽象类中定义了一个产生对象的方法,由具体的子类来实现到底产生什么样的对象
工厂方法模式是简单工厂模式的进一步抽象化和推广,工厂方法模式里不再只由一个工厂类决定那一个产品类应当被实例化,这个决定被交给抽象工厂的子类去做。
它的组成:
1)抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
2)具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
3)抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
4)具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
工厂方法模式使用继承自抽象工厂角色的多个子类来代替简单工厂模式中的“上帝类”。这样使得结构变得灵活起来——当有新的产品产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有的代 码。可以看出工厂角色的结构也是符合开闭原则的!
具体实例:
//抽象工厂
public  abstract  class CarFactory {
abstract Vehicle create();
}
//具体工厂
public  class PlaneFactory  extends CarFactory{
public Vehicle create() {
return  new Plane();
}
}
//具体工厂
public class BroomFactory  extends CarFactory{
public Vehicle create() {
return  new Broom();
}
}
//测试类
public  class Test {
public  static  void main(String[] args) {
CarFactory factory =  new BroomFactory();
Moveable m = factory.create();
m.run();
}
}
简单工厂与工厂方法比较:
工厂方法模式和简单工厂模式在定义上的不同是很明显的。工厂方法模式的核心是一个抽象工厂类,而不像简单工厂模式, 把核心放在一个具体的子类上。工厂方法模式可以允许很多实例工厂类从抽象工厂类继承下来, 从而可以在实际上成为多个简单工厂模式的综合,从而推广了简单工厂模式。 
反过来讲,简单工厂模式是由工厂方法模式退化而来。设想如果我们非常确定一个系统只需要一个实的工厂类, 那么就不妨把抽象工厂类合并到实的工厂类中去。而这样一来,我们就退化到简单工厂模式了。
设计原则(依赖倒置原则):要依赖抽象,不要依赖具体类
高层组件和底层组件依赖于一个抽象产品。
在实际开发中,注意几个原则,可以避免违反依赖倒置原则
1)变量不可以持有具体类的引用。如果使用new,就会持有具体类的引用。
2)不要让类派生自具体类。如果派生于具体类,就会依赖于具体类,一般派生于接口或抽象类。派生具体类会使子类具有一些不要的功能,而派生接口或抽象类,会将共享的部分提出,变化的部分共子类来实现。
3)不要覆盖基类中已经实现的方法。如果覆盖基类已实现的方法,那么基类就不适合被继承,基类实现的方法,应该由子类共享。

小思考 选择抽象类还是接口,一般来说倘若子类都具有一些相同的功能,且功能的具有相同的行为,则使用抽象类,而把相同的功能且具有不同变化的行为交给子类来实现。倘若子类都具全部的功能且行为不同,则就用接口,并且接口可以避免java中的单继承限制特点。

三 抽象工厂模式

它主要是用来创建一系列的产品族,抽象工厂的任务就是定义一个负责创建一组产品的接口。工厂方法其实就是潜伏在抽象工厂里面。
举例说明:
//抽象工厂类
public  abstract  class AbstractFactory {
public  abstract Vehicle createVehicle();
public  abstract Weapon createWeapon();
public  abstract Food createFood();
}
//具体工厂类,其中Food,Vehicle,Weapon是抽象类,
public class DefaultFactory  extends AbstractFactory{
@Override
public Food createFood() {
return  new Apple();
}
@Override
public Vehicle createVehicle() {
return  new Car();
}
@Override
public Weapon createWeapon() {
return  new AK47();
}
}
//测试类
public  class Test {
public  static  void main(String[] args) {
AbstractFactory f =  new DefaultFactory();
Vehicle v = f.createVehicle();
v.run();
Weapon w = f.createWeapon();
w.shoot();
Food a = f.createFood();
a.printName();
}
}

工厂方法和抽象工厂的比较
工厂方法使用的是类,而抽象工厂使用的是对象。他们都负责创建对象,工厂方法通过继承来让子类来创建具体的实例化类,而抽象工厂则是通过对象的组合来创建,因为抽象工厂要创建一系列的产品族。利用工厂方法来创建对象的时候需要扩展一个类,并且覆盖它的工厂方法。抽象工厂需要一个大基类,这个大基类包括了所有产品的创建的“工厂方法”。
当需要创建产品家族和想让制造的相关产品集合起来,就是用抽象工厂。
当还不知道以后需要实例化哪些类的时候,可以使用工厂方法。
工厂方法,就是一个基类中包含了一个工厂方法,让子类来决定创建哪些自己的类型产品。
抽象工厂,就是一个基类中包含了创建一系列产品的方法,让子类来实例化具体的对象集合。
整体比较:
(1)简单工厂模式是由一个具体类创建其他类的实例,父类是相同的,父类是具体的。
(2)工厂方法模式是由一个抽象的父类定义的抽象方法,子类负责生成具体的对象,这样做的目的是将类的实例化操作延迟到子类中完成。
(3)抽象工厂模式提供一个创建一系列相关或相互依赖对象接口,而无须指定他们具体的类。它针对的是有多个产品的等级结构。而工厂方法模式针对的是一个产品的等级结构。
要点
1)所有的工厂都是用来封装对象的创建的
2)工厂方法使用继承:把对象的创建委托给子类,子类实现工厂方法来创建对象
3)抽象工厂使用对象组合:对象的创建被实现在工厂接口所暴露的方法中
4)所有的工厂模式都通过减少应用程序和具体类之间的依赖促进松耦合
5)工厂方法允许将类实例化延迟到子类进行
6)抽象工厂创建相关的对象家族,而不需要依赖于他们的具体类


本文转自 zhao_xiao_long 51CTO博客,原文链接:http://blog.51cto.com/computerdragon/1155657
相关文章
|
26天前
|
设计模式 算法 Java
Java中的设计模式:提升代码质量的秘诀
【8月更文挑战第23天】在Java开发中,设计模式是提高代码可读性、可维护性和扩展性的强有力工具。本文通过浅显易懂的语言和实际案例,探讨几种常见的设计模式及其在Java中的应用,旨在帮助开发者更好地理解并运用这些模式来优化自己的代码结构。
38 2
|
3天前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
|
3天前
|
设计模式 安全 算法
【Java面试题汇总】设计模式篇(2023版)
谈谈你对设计模式的理解、七大原则、单例模式、工厂模式、代理模式、模板模式、观察者模式、JDK中用到的设计模式、Spring中用到的设计模式
【Java面试题汇总】设计模式篇(2023版)
|
3天前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑】设计模式——原型模式
对比原型模式和传统方式的实现思路、代码方案、优缺点,阐述原型模式的使用场景,以及深拷贝、浅拷贝等相关概念,并扩展原型模式在Spring源码中的应用。
【Java笔记+踩坑】设计模式——原型模式
|
30天前
|
设计模式 存储 Java
【十】设计模式~~~结构型模式~~~享元模式(Java)
文章详细介绍了享元模式(Flyweight Pattern),这是一种对象结构型模式,通过共享技术实现大量细粒度对象的重用,区分内部状态和外部状态来减少内存中对象的数量,提高系统性能。通过围棋棋子的设计案例,展示了享元模式的动机、定义、结构、优点、缺点以及适用场景,并探讨了单纯享元模式和复合享元模式以及与其他模式的联用。
【十】设计模式~~~结构型模式~~~享元模式(Java)
|
19天前
|
设计模式 缓存 算法
揭秘策略模式:如何用Java设计模式轻松切换算法?
【8月更文挑战第30天】设计模式是解决软件开发中特定问题的可重用方案。其中,策略模式是一种常用的行为型模式,允许在运行时选择算法行为。它通过定义一系列可互换的算法来封装具体的实现,使算法的变化与客户端分离。例如,在电商系统中,可以通过定义 `DiscountStrategy` 接口和多种折扣策略类(如 `FidelityDiscount`、`BulkDiscount` 和 `NoDiscount`),在运行时动态切换不同的折扣逻辑。这样,`ShoppingCart` 类无需关心具体折扣计算细节,只需设置不同的策略即可实现灵活的价格计算,符合开闭原则并提高代码的可维护性和扩展性。
36 2
|
19天前
|
设计模式 Java
Java 设计模式之谜:工厂模式与抽象工厂模式究竟隐藏着怎样的神奇力量?
【8月更文挑战第30天】在Java编程中,设计模式为常见问题提供了高效解决方案。工厂模式与抽象工厂模式是常用的对象创建型设计模式,能显著提升代码的灵活性、可维护性和可扩展性。工厂模式通过定义创建对象的接口让子类决定实例化哪个类;而抽象工厂模式则进一步提供了一个创建一系列相关或相互依赖对象的接口,无需指定具体类。这种方式使得系统更易于扩展和维护。
29 1
|
19天前
|
设计模式 Java
重构你的代码:探索Java中的混合、装饰器与组合设计模式
【8月更文挑战第30天】在软件开发中,设计模式为特定问题提供了结构化的解决方案,使代码更易理解、维护及扩展。本文将介绍三种常用的 Java 设计模式:混合模式、装饰器模式与组合模式,并附有示例代码展示实际应用。混合模式允许通过继承多个接口或抽象类实现多重继承;装饰器模式可在不改变对象结构的情况下动态添加新功能;组合模式则通过树形结构表示部分-整体层次,确保客户端处理单个对象与组合对象时具有一致性。
14 1
|
29天前
|
设计模式 算法 安全
Java编程中的设计模式:提升代码的可维护性和扩展性
【8月更文挑战第19天】在软件开发的世界里,设计模式是解决常见问题的一种优雅方式。本文将深入探讨Java编程语言中常用的几种设计模式,并解释如何通过这些模式来提高代码的可维护性和扩展性。文章不涉及具体的代码实现,而是侧重于理论和实践相结合的方式,为读者提供一种思考和改善现有项目的新视角。
|
30天前
|
设计模式 Java
常用设计模式介绍~~~ Java实现 【概念+案例+代码】
文章提供了一份常用设计模式的全面介绍,包括创建型模式、结构型模式和行为型模式。每种设计模式都有详细的概念讲解、案例说明、代码实例以及运行截图。作者通过这些模式的介绍,旨在帮助读者更好地理解源码、编写更优雅的代码,并进行系统重构。同时,文章还提供了GitHub上的源码地址,方便读者直接访问和学习。
常用设计模式介绍~~~ Java实现 【概念+案例+代码】