zoukankan      html  css  js  c++  java
  • 设计模式之-抽象工厂模式

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

    接下来我就以一款游戏来模拟一下场景,这个游戏分为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

  • 相关阅读:
    openwrt的内核版本是在哪个文件中指定的?
    git如何将一个分支合并到另一个分支?
    cygwin如何下编译安装tmux?
    如何合并ts文件?
    在cygwin下创建的文件位于windows的哪个目录下?
    linux shell的for循环语法是怎样的?
    内部类访问局部变量时,为什么需要加final关键字
    Java8函数式编程的宏观总结
    Maven私服使用经验总结
    java关于Integer设置-128到127的静态缓存
  • 原文地址:https://www.cnblogs.com/hhzblogs/p/10365366.html
Copyright © 2011-2022 走看看