工厂方法与抽象工厂

目录

  • 本篇概述
  • 工厂方法 Factory Method
    • 适用情况
    • 适用举例
    • 例示代码
      • 基类
      • 衍生类
      • 使用
    • 适用举例2
    • 例示代码2
      • 衍生类
    • 使用
    • 总结
  • 抽象工厂 Abstract Factory
    • 适用情况
    • 适用举例
    • 例示代码
      • 基类
      • 衍生类
      • 使用
    • 总结
  • 两者的比较

本篇概述

工厂方法和抽象工厂都是一种对象创建型模式,在不同方面上解决了一些在对象创建上发生的设计问题。笔者学习的时候难以理解两者的区分,查阅较多资料后作此总结。

工厂方法 Factory Method

适用情况

当要根据不同的状况获取不同的类的实例对象时。

当一个类要实例化一个类对象却不知道该对象属于的类时。

总体来说就是要选择不同的类,延后实例化。

适用举例

工厂方法较为常用。

一款RPG游戏,一个铁匠铺要根据用户的输入打造不同类型的剑。

这种情况下,你事先不知道用户要打造哪个类型的剑,又不想将剑的类型在外部暴露出来,就可以使用工厂模式。

例示代码

代码主要展示结构设计,并不一定合乎使用情理,也不一定最优。

还要注意的是,虽然这里只是使用了普通的构造函数,但有很多对象的构造涉及较复杂的过程,使用工厂模式也能较好地将其过程封装起来。

基类

在这里我们用到两个基类,剑和剑工厂(这里就不用铁匠铺来描述了)

//剑的基类
public class Sword
{
    //一些代码
}

//铁匠铺
public class SwordFactory
{
    //这里设置成虚函数,使之可以被继承。为什么剑工厂会被继承,稍后会讲到。
    public virtual Sword CreateSword(string type)
    {
        switch (type)
        {
            case "LongSword":
            	return LongSword();
            //还有其他的剑的话可以在这里添加case代码
        }
        return Sword();
    }
}

衍生类

这里为了缩短篇幅只用一种剑举例,其他剑同理。

//长剑
public class LongSword : Sword
{
    //一些代码
}

使用

这样,我们就可以在不触及剑对象的创建和类型的前提下,根据情况创建需要的对象了。

SwordFactory sf = new SwordFactory();
Sword longSword = sf.CreateSword("LongSword");
//拿着长剑爱干嘛干嘛

适用举例2

后来,我们进入了魔界,魔界的铁匠铺能够生产恶魔之剑,但不能生产出长剑。

在先前,我们根本不知道恶魔之剑是什么,更别说实例化出恶魔之剑。这时,工厂模式继续发挥出他的作用。

例示代码2

我们不对基类做改变,而是使用一个新的工厂去继承原来的工厂。

衍生类

//魔剑
public class DevilSword : Sword
{
    //一些代码
}

//魔界铁匠铺
public class DevilSwordFactory
{
    //这里设置成虚函数,使之可以被继承。为什么剑工厂会被继承,稍后会讲到。
    public virtual Sword CreateSword(string type)
    {
        switch (type)
        {
            case "DevilSword":
            	return DevilSword();
            //还有其他的剑的话可以在这里添加case代码
        }
        return Sword();
    }
}

使用

这样,我们依旧可以在不暴露剑的类型和剑的制作方法的情况下获得一把魔剑的实例。

SwordFactory sf = new DevilSwordFactory();
Sword devilSword = sf.CreateSword("DevilSword");
//接下来带着魔剑爱干嘛干嘛

啥?你说你连铁匠铺都不想暴露?

那写个制造工厂的工厂不就好了 ??

总结

工厂模式是一个较为常用的设计模式,他的思想是借助其他对象实例化其他对象,可以有效将一部分代码封装(买剑不需要知道剑是怎么样生产出来的),或者将实例化的任务交给子类(魔界的铁匠铺才会打造魔剑)。但在类多的时候,有可能需要较多的工厂,造成类冗余。

在工厂只需要负责实例化一种对象时,C++可以用模板来解决类冗余的问题(由于笔者不会实现C#模板全特化,网上搜较多资料也未找到可行的方法,无法将书中的C++描述转化过来,这里就不多说了QAQ)

抽象工厂 Abstract Factory

适用情况

当创建的一系列对象存在互相依赖的关系时。

适用举例

在一款射击的游戏中,它有着这样的设定:

射击类武器有:手枪,步枪……。

每种射击类又有多种弹药:普通弹药,破甲型弹药……。

每种武器只能射击相对应的弹药,在捡到该武器的时候会赠送一些普通弹药。

在这种情况下,“子弹”和“枪”有了一定的联系,我们要生成一把射击类武器,就要生成对应的子弹。为了让用户生成的子弹和弹药类型必定匹配,我们就可以使用抽象工厂解决这一问题。

例示代码

代码主要展示结构设计,并不一定合乎使用情理,也不一定最优。

基类

首先,要有三个大基类:武器,弹药,工厂。

在这里三者都是抽象类。

这里为了缩短篇幅只用手枪举例,其他枪同理。

//弹药
public abstract class Bullet
{
    //代码,什么都行
}

//武器
public abstract class Gun
{
    //代码,什么都行
}

工厂:

由于抽象类无法实例化,这里利用静态方法来获取一个工厂的实例。

若设计的类有默认值,可使用其他方法获得实例,比如说基于一个List进行原型复制,或者单例。

public abstract class GunFactory
{
    //通过引索获得工厂的实例
    public static GunFactory GetFactory(string type)
    {
        switch (type)
        {
            case "Pistol":
                return new PistolFactory();
            //还有其他的工厂的话可以在这里添加case代码
        }
        return null;
    }
    public abstract Bullet CreateBullet();
    public abstract Gun CreateGun();
}

衍生类

//手枪弹药
public class PistolBullet : Bullet
{
	//代码
}

//手枪
public class Pistol: Gun
{
    //代码
}

//手枪工厂
public class PistolFactory : GunFactory
{
    public override Bullet CreateBullet()
    {
        return new PistolBullet();
    }

    public override Gun CreateGun()
    {
        return new PistolBullet();
    }
}

使用

通过静态方法实例化出工厂,就可以产出相匹配的枪和子弹了。

GunFactory pistolFac = GunFactory.GetFactory("Pistol");
Gun pistol = pistolFac.CreateGun();
Bullet bullet = pistolFac.CreateBullet();
//接下来爱干嘛干嘛

总结

抽象工厂主要的意图在于解决生成的多个对象相关联的问题。在没有关联的时候,由于要实现较多无用接口,使用抽象工厂反而会降低效率。

两者的比较

工厂方法:注重于对象的延迟生成,较多情况都可以使用,工厂可以只生产一种对象。

抽象工厂:注重于生成对象类型的关联性,在对象间有较强的关系时推荐使用,工厂一般要生成两种或以上对象(不然哪来的“关联”)

抽象工厂可以用也通常用工厂方法来实现(上面的例示代码便是用工厂方法实现),但同时也可以用原型模式来实现。

原文地址:https://www.cnblogs.com/yasoudream/p/12635703.html

时间: 2024-08-09 07:50:49

工厂方法与抽象工厂的相关文章

Java设计模式—工厂方法模式&抽象工厂模式

工厂方法模式与抽象工厂模式都是设计模式中重要而且常见的模式.       工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 通用类图如下: 在工厂方法模式中,抽象产品类Product负责定义产品的共性,实现对事物最抽象的定义:Creator为抽象创建 类,也就是抽象工厂,具体如何创建产品类是由具体的实现工厂ConcreteCreator完成的. 工厂方法模式的扩展方式有很多种,下边是工厂方法模式一个比较实用的源代码: 抽象产品类: pub

设计模式系列---简单工厂、工厂方法、抽象工厂

前言,最近看spring的源代码.发现之前没有完全弄懂(工厂方法.抽象工厂)的区别. spring中代理对象的产生,是通过代理工厂(工厂模式),首先spring中的代理是使用jdk或者cglib的代理,只要看目标类是否实现接口. public class ProxyFactory extends ProxyCreatorSupport { //createAopProxy()方法是通过AopProxyFactory获取AopProxy(JDK,CGLIB) public Object getPr

【转】设计模式:简单工厂、工厂方法、抽象工厂之小结与区别

简单工厂,工厂方法,抽象工厂都属于设计模式中的创建型模式.其主要功能都是帮助我们把对象的实例化部分抽取了出来,优化了系统的架构,并且增强了系统的扩展性. 本文是本人对这三种模式学习后的一个小结以及对他们之间的区别的理解. 简单工厂 简单工厂模式的工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例. 不修改代码的话,是无法扩展的. 工厂方法 工厂方法是针对每一种产品提供一个工厂类.通过不同的工厂实例来创建不同的产品实例. 在同一等级结构中,支持增加任意产品. 抽象工厂 抽象工厂是应

工厂模式—工厂方法与抽象工厂的战争

概述 什么是工厂方法?什么是抽象工厂? 工厂方法是指工厂生产产品,而抽象工厂是生产产品系列.例如,工厂方法是只生产运输工具比如马车.公共汽车.自行车,而抽象工厂生产轮胎.螺丝钉交通工具零件. 工厂方法模式定义了一个创建对象的接口,但由子类决定实例化的类是哪一个.工厂方法让类把实例化推迟到子类. 抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类. 简单工厂 交通工具创建者类 public interface VehicleFactory { Vehicle creat

简单工厂、工厂方法、抽象工厂、策略模式、策略与工厂的区别

结合简单示例和UML图,讲解工厂模式简单原理. 一.引子 话说十年前,有一个爆发户,他家有三辆汽车(Benz(奔驰).Bmw(宝马).Audi(奥迪)),还雇了司机为他开车.不过,爆发户坐车时总是这样:上Benz车后跟司机说"开奔驰车!",坐上Bmw后他说"开宝马车!",坐上 Audi后他说"开奥迪车!".你一定说:这人有病!直接说开车不就行了?!而当把这个爆发户的行为放到我们程序语言中来,我们发现C语言一直是通过这种方式来坐车的!幸运的是这种有

简单工厂、工厂方法与抽象工厂大比拼

简单工厂.工厂方法和抽象工厂都属于设计模式创建型,严格意义上简单工厂不属于23设计模式之一(违背了开闭原则),本文为了完整描述三工厂演变过程,对三工厂进行了整体的总结和学习,并通过三者之间的特点比较总结出各自的优缺点. 一.简单工厂: 在没有工厂之前,大家都是自给自足,生产一部车或其他工具都是自己来完成,有了工厂之后,告诉它需求就会出来相应的产品,但生产化水平比较低,工厂分工不太明确,社会上只有一个工厂,不论卡车还是公交车都由它来完成,相当于一个工厂多条生产线. 类图: 代码: /*******

设计模式:简单工厂、工厂方法、抽象工厂之小结与区别 (转)

简单工厂,工厂方法,抽象工厂都属于设计模式中的创建型模式.其主要功能都是帮助我们把对象的实例化部分抽取了出来,优化了系统的架构,并且增强了系统的扩展性. 本文是本人对这三种模式学习后的一个小结以及对他们之间的区别的理解. 简单工厂 简单工厂模式的工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例. 不修改代码的话,是无法扩展的. 工厂方法 工厂方法是针对每一种产品提供一个工厂类.通过不同的工厂实例来创建不同的产品实例. 在同一等级结构中,支持增加任意产品. 抽象工厂 抽象工厂是应

重头开始学23种设计模式:三大工厂(简单工厂,工厂方法,抽象工厂)

在开发当中我们经常会使用三个设计模式,来帮我们解决项目代码的可扩展性. 在简单工厂,工厂方法,抽象工厂这三个设计模式当中,代码其实都很简单,主要是要理解运用. 简单工厂: 简单工厂说白了,就是利用Switch根据传递的参数,进行实例化. 工厂方法: 工厂方法,为解决每次都去增加Swicth的简单工厂的升级.为每一个产品提供一个工厂类. 抽象工厂: 抽象工厂,我觉得也是对工厂方法的再次升级,工厂方法每次只能创作一个产品,而抽象工厂就是产品线的产品族. 总结下,从网上找到一个大牛的回复: 我认为不能

简单工厂、工厂方法、抽象工厂之小结、区别

很多时候,我发现这三种设计模式难以区分,常常会张冠李戴闹了笑话.很有必要深入总结一下三种设计模式的特点.相同之处和不同之处. 1 本质 三个设计模式名字中都含有“工厂”二字,其含义是使用工厂(一个或一系列方法)去生产产品(一个或一系列类的实例). 另外,有时候,我们常常会将生产产品的一个或一系列方法封装到一个类中,我习惯把这个类叫做“工厂类”:而被实例化的类称作“产品类”. 2 简单工厂 工厂类(SimpleFactory)拥有一个工厂方法(create),接受了一个参数,通过不同的参数实例化不

简单工厂、工厂方法、抽象工厂区别

设计模式:简单工厂.工厂方法.抽象工厂之小结与区别 大话设计模式之简单工厂模式.抽象工厂模式及工厂方法模式的比较 抽象工厂模式-与-工厂方法模式区别 在简单工厂模式下,工人要想到种植萝卜还是白菜,在工厂模式下,工人想到是种植根菜还是茎菜,而在抽象工厂模式下,则关心种植基因菜还是非基因菜