• 设计模式之-抽象工厂模式


    抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。根据里氏替换原则,任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。换言之,也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。

    接下来我就以一款游戏来模拟一下场景,这个游戏分为5大门派(金,木,水,火,土),每个门派又有3种类型的技能(法攻技能/障碍技能/辅助技能),而每个门派的的3种类型的技能又不同。

    以下是各个门派技能一览:

    金系     法攻技能(金光乍现)  障碍技能(流连忘返)   辅助技能(天生神力)

    木系     法攻技能(摘叶飞花)  障碍技能(见血封喉)   辅助技能(揠苗助长)

    水系     法攻技能(滴水穿石)  障碍技能(三九严寒)   辅助技能(防微杜渐)

    火系     法攻技能(举火焚天)  障碍技能(心醉神迷)   辅助技能(心醉神迷)

    土系     法攻技能(落土飞岩)  障碍技能(有心无力)   辅助技能(鞭长莫及)

    接下来我们用抽象工厂来实现每个门派各种技能的释放,并且使得这个实现具有很高的扩展性,当你要新增一个门派时,完全不用去改动以前的代码(开闭原则)。

    抽象工厂代码

    namespace AbstractFactory.Factory
    {
        /// <summary>
        /// 抽象一个技能工厂
        /// </summary>
        public abstract class BaseFactory
        {
            /// <summary>
            /// 法术攻击技能
            /// </summary>
            /// <returns></returns>
            public abstract ISkill CreateMagicAttackSkill();
            /// <summary>
            /// 障碍技能
            /// </summary>
            /// <returns></returns>
            public abstract ISkill CreateObstacleSkill();
            /// <summary>
            /// 辅助技能
            /// </summary>
            /// <returns></returns>
            public abstract ISkill CreateAuxiliarySkill();
        }
    }

    具体工厂代码(金系门派)

    namespace AbstractFactory.Factory.Gold
    {
        /// <summary>
        /// 创建金系门派技能工厂
        /// </summary>
        public class GoldSectsSkillFactory : BaseFactory
        {
            /// <summary>
            /// 创建法攻技能类
            /// </summary>
            /// <returns></returns>
            public override ISkill CreateMagicAttackSkill()
            {
                return new GoldMagicAttackSkill();
            }
            /// <summary>
            /// 创建障碍技能类
            /// </summary>
            /// <returns></returns>
            public override ISkill CreateObstacleSkill()
            {
                return new GoldObstacleSkill();
            }
            /// <summary>
            /// 创建辅助技能类
            /// </summary>
            /// <returns></returns>
            public override ISkill CreateAuxiliarySkill()
            {
                return new GoldAuxiliarySkill();
            }
        }
    }

    抽象产品

    namespace AbstractFactory.Interface
    {
        /// <summary>
        /// 门派接口(抽象产品)
        /// </summary>
        public interface ISkill
        {
            /// <summary>
            /// 释放技能
            /// </summary>
            void ReleaseSkill();
        }
    }

    具体产品

    namespace AbstractFactory.Factory.Gold
    {
        /// <summary>
        /// 辅助技能类
        /// </summary>
        public class GoldAuxiliarySkill : ISkill
        {
            public void ReleaseSkill()
            {
                Console.WriteLine("金系辅助技能-天生神力");
            }
        }
    }
    namespace AbstractFactory.Factory.Gold
    {
        /// <summary>
        /// 法术攻击技能类
        /// </summary>
        public class GoldMagicAttackSkill : ISkill
        {
            public void ReleaseSkill()
            {
                Console.WriteLine("金系法术攻击技能-金光乍现");
            }
        }
    }
    namespace AbstractFactory.Factory.Gold
    {
        /// <summary>
        /// 障碍技能类
        /// </summary>
        public class GoldObstacleSkill : ISkill
        {
            public void ReleaseSkill()
            {
                Console.WriteLine("金系障碍技能-流连忘返");
            }
        }
    }

    接下来就是调用了:

    BaseFactory goldFactory = new GoldSectsSkillFactory();//金系技能工厂
    ISkill goldMagicAttackSkill = goldFactory.CreateMagicAttackSkill();//创建法术攻击技能类
    goldMagicAttackSkill.ReleaseSkill();//释放技能
    
    ISkill goldAuxiliarySkill = goldFactory.CreateAuxiliarySkill();//创建辅助技能类
    goldAuxiliarySkill.ReleaseSkill();//释放技能

    结果如下:

     以上就完成了抽象工厂实现金系门派技能的释放。

    那么问题来了,当我们想再新增一个门派时呢,这里我们就来演示下新增一个木系门派。

    以下是我们新增门派之前的项目结构图:

    新增之后:

     

    调用代码:

    namespace AbstractFactory
    {
        class Program
        {
            static void Main(string[] args)
            {
                try
                {
                    BaseFactory goldFactory = new GoldSectsSkillFactory();//金系技能工厂
                    ISkill goldMagicAttackSkill = goldFactory.CreateMagicAttackSkill();//创建法术攻击技能类
                    goldMagicAttackSkill.ReleaseSkill();//释放技能
    
                    ISkill goldAuxiliarySkill = goldFactory.CreateAuxiliarySkill();//创建辅助技能类
                    goldAuxiliarySkill.ReleaseSkill();//释放技能
    
                    BaseFactory woodFactory = new WoodSectsSkillFactory();//木系技能工厂
                    ISkill woodMagicAttackSkill = woodFactory.CreateMagicAttackSkill();//创建法术攻击技能类
                    woodMagicAttackSkill.ReleaseSkill();//释放技能
    
                    ISkill woodAuxiliarySkill = woodFactory.CreateAuxiliarySkill();//创建辅助技能类
                    woodAuxiliarySkill.ReleaseSkill();//释放技能
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                Console.ReadKey();
            }
        }
    }

     结果如下:

     以上就是抽象工厂完美的扩展。

     源代码地址:https://github.com/houzhenhuang/DesignPattern

  • 相关阅读:
    JavaCV音视频开发宝典:录制vp8和vp9编码的webm格式视频,以mp4转webm为例
    JavaCV音视频开发宝典:使用JavaCV采集windows系统声音并录制成mp3音频文件(FFmpeg采集windows系统声音)
    JavaCV音视频开发宝典:使用JavaCV和springBoot实现httpflv直播服务,无需流媒体服务,浏览器网页flv.js转封装方式播放rtsp,rtmp和桌面投屏实时画面
    linux用户用户组与ACL
    QUIC协议详解
    技术分享 | 黑盒测试方法论—等价类
    技术分享 | 这些常用测试平台,你们公司在用的是哪些呢?
    干货 | 测试专家(前阿里P8)聊测试职业发展常见瓶颈
    如何做好测试开发?| 破解测试人技术成长常见的 3 种错误思维!
    技术分享 | 黑盒测试方法论—因果图
  • 原文地址:https://www.cnblogs.com/hhzblogs/p/10365366.html
Copyright © 2020-2023  润新知