夸克之书

  • 首页
  • 科普
  • 笔记
  • .NET/C#
  • 物联网
  • 算法
  • Linux
  • 树莓派
夸克之内,别有洞天
  1. 首页
  2. .NET/C#
  3. 正文

23种常见的设计模式(3):抽象工厂模式

2020-01-01 2844点热度 0人点赞 0条评论

在上一篇(工厂方法模式)中我们发现了一个问题,就是一个工坊里面只能生产一个产品?现在问题就来了:突然客户要求,每种产品要分为两种型号,即型号1和型号2。

这时就需要我们对我们的工坊进行改造了,给我们的工坊添加两条生产线,让每个工坊可以同时生产不同型号的产品。

首先是我们的产品,我们要将我们的产品划分为两种不同的型号,分别是型号1和型号2。于是我们把每种产品抽象出来,以产品A为例:

/// <summary>
/// 抽象产品A
/// 集成了工厂类,都是从工厂当中生产的嘛
/// </summary> 
public abstract class AbstractProductA : IFactory
 {
     /// <summary>
     /// 名称
     /// </summary>
     public abstract string Name { get; }

     /// <summary>
     /// 型号
     /// </summary>
     public abstract string Model { get; }

     /// <summary>
     /// 产品内容
     /// </summary>
     public override void Show()
     {
         Console.WriteLine($"我是产品{Name},不过我是型号{Model}。");
     }
 }

然后分别再去实现产品A的两种不同型号。

/// <summary>
/// 产品A的型号1
/// </summary>
public class ProductAModel1 : AbstractProductA
{
    public override string Name
    {
        get
        {
            return "A";
        }
    }

    public override string Model
    {
        get
        {
            return "1";
        }
    }
}

/// <summary>
/// 产品A的型号1
/// </summary>
public class ProductAModel2 : AbstractProductA
{
    public override string Name
    {
        get
        {
            return "A";
        }
    }

    public override string Model
    {
        get
        {
            return "2";
        }
    }
}

产品B,产品C依次类推。

好了,现在我们生产的产品已经完成改造了。接下来是对我们的工坊进行进一步的改造,为我们的工坊添加两天生产线,可以同时生产不同型号的两种产品。

/// <summary>
/// 抽象工厂类
/// 用于创建具体的工厂
/// </summary>
public abstract class IWorkshop
{
    /// <summary>
    /// 型号1的生产线
    /// </summary>
    /// <returns></returns>
    public abstract IFactory CreateModel1();

    /// <summary>
    /// 型号2的生产线
    /// </summary>
    /// <returns></returns>
    public abstract IFactory CreateModel2();
}

接下来改造A产品的工坊。

/// <summary>
/// 生产A产品的工坊
/// </summary>
public class WorkshopA : IWorkshop
{
    public override IFactory CreateModel1()
    {
        return new ProductAModel1();
    }

    public override IFactory CreateModel2()
    {
        return new ProductAModel2();
    }
}

依次类推,工坊B和工坊C也做同样的改造。

这时,我们的整个工厂又可以重新开工了,试试改造后的生产线是否正常工作。

static void Main(string[] args)
{
    IWorkshop a = new WorkshopA();
    IWorkshop b = new WorkshopB();
    IWorkshop c = new WorkshopC();
    IFactory factory;

    Console.WriteLine("型号1的产品:");
    factory = a.CreateModel1();
    factory.Show();
    factory = b.CreateModel1();
    factory.Show();
    factory = c.CreateModel1();
    factory.Show();

    Console.WriteLine();
    Console.WriteLine("型号2的产品:");
    factory = a.CreateModel2();
    factory.Show();
    factory = b.CreateModel2();
    factory.Show();
    factory = c.CreateModel2();
    factory.Show();

    Console.ReadKey(false);
}

运行结果:

%title插图%num
抽象工厂模式运行demo

可以看出来,相对于工厂模式。我们完成了对一个同类型的产品类的扩展,解决了原来一个工厂只能完成一件事的弊端。其实这就是抽象工厂模式的定义:为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类。

%title插图%num
抽象工厂模式类图

通过上面例子可以看出抽象工厂模式的有点:

· 良好的封装性,每个产品的不同实现不是高层次模块需要关心的。高层次模式小只需要知道如何调用即可(Show方法)。
· 产品族内的约束为非公开状态。

缺点:

虽然抽象工厂模式优点很明显,但是缺点也不容小视。从工厂方法模式改造为抽象工厂模式之后对我们的代码改造巨大,而且每增加一个产品的型号之后,需要修改对应的工坊类,这就违反了“开闭原则”。但这种复杂也是相对的,结合工厂方法模式,可以看出抽象工厂模式难于扩展也是在单独一个产品族内部的,比如要增加一个一个产品型号,要修改的地方非常非常多。但是要增加一个产品却很容易,增加一个工坊即可。

总结一下,抽象工厂模式可以用于有一个共同约束情况下的对象扩展。比如我们要实现一个跨平台的音频播放组件,无论在哪一个平台下,都有播放和暂停的操作。我们只需要建立对应平台的工厂实现即可。那样就可以屏蔽掉对不同操作系统底层的调用,用户只需要关心如何去调用播放和暂停方法即可。

本篇代码下载:点击下载

本作品采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可
标签: 暂无
最后更新:2020-12-13

afirefish

这个人很懒,什么都没留下

打赏 点赞
< 上一篇
下一篇 >

文章评论

您需要 登录 之后才可以评论
放松一下
https://www.quarkbook.com/wp-content/uploads/2021/05/凤凰传奇-海底(Live).flac
分类
  • .NET/C#
  • Linux
  • 树莓派
  • 物联网
  • 科普
  • 笔记
  • 算法
  • 默认
最新 热点 随机
最新 热点 随机
维持宇宙的四种“力量”——关于四大基本力 MinGW图形安装界面里面没有mingw32 make.exe解决办法 Windows Server 2022安装Intel I225-V/I226-V驱动 System.Text.Json与Newtonsoft.Json Json序列化与反序列化性能对比 R86S散热改造 Windows移除多余输入法'Unknown Locale (qaa-Latn)'
Windows Server 2022安装Intel I225-V/I226-V驱动MinGW图形安装界面里面没有mingw32 make.exe解决办法维持宇宙的四种“力量”——关于四大基本力
文摘 在ASP.NET Core中使用Redis作为Session 23种常见的设计模式(1):单例模式 获取访问IP信息接口(暂不开放) 树莓派4B配置U盘启动 谈谈Js的回调函数
最近评论
afirefish 发布于 4 个月前(11月28日) 非常感谢,非常棒!
》随缘《 发布于 4 个月前(11月20日) 最新【一键处理】方法: https://github.com/MrXhh/VSTools/rele...
管理员 发布于 9 个月前(06月22日) emmmm....服务器好一点???
wking 发布于 10 个月前(05月23日) 请问贵博客是怎么优化的,网页响应速度非常快。我博客同样的WordPress和kratos主题,但点一...
去月球 发布于 1 年前(01月17日) 如果使用CSI的摄像头应该怎么修改命令呢
书签
  • 打赏
  • 毒鸡汤
  • 米店
  • 金鱼直播间

COPYRIGHT © 2022 quarkbook.com. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

蜀ICP备15036129号-9

登录
注册|忘记密码?