大话设计模式:工厂模式

一、什么是工厂模式
给一个创建对象的接口,让其子类决定创建哪个具体对象.

允许接口创建对象,但使用哪个类来创建对象,则是交由子类决定的。工厂模式像是一个工厂群,工厂A生产A产品,工厂B生产B产品,你有什么东西要生产,我就有什么工厂负责给你生产.

UML图

在这里插入图片描述

二、适用场景

多同基类的子类需要生成,比如怪物工厂,野怪A 野怪B等等,他们可以建立一套怪物的对象 类,然后有对应的工厂和具体工厂.在工厂里面怪物已经定义好了,外界只需要调用工厂类创建即可,不用关心对象具体是怎么创建的.

三、优缺点

优点
解决了简单工厂的不符合封闭原则的情况
实现解耦合,将创建和使用分开
将创建对象封装,减少代码重复度.
缺点
若要增加对象,则要增加对应的工厂类.
创建哪一个对象的逻辑交给了客户端.

四、大话中的例子

雷锋工厂的例子,学雷锋的有大学生/有雷锋社区, 工厂类就需要对应的大学生工厂/雷锋社区工厂,你要大学生去做好事还是雷锋社区去做好事,声明实例一个对应的工厂就好,这个工厂可以创建你要的.

五、我的例子
using System;

namespace FactoryMode
{
    class Program
    {
        static void Main(string[] args)
        {

            Console.WriteLine("=========与飞段角都的战斗==========");
            CreateNinja shikamaruFact = new CreateShikamaru();//需要客户端确定生产哪个对象
            KonohaNinja shikamaru = shikamaruFact.CreateObject();
            Console.WriteLine("=========第一回合==========");
            shikamaru.UseKunai();
            shikamaru.ExclusiveSkill();
            CreateNinja narutoFact = new CreateNaruto();
            KonohaNinja naruto = narutoFact.CreateObject();
            Console.WriteLine("=========第二回合==========");
            naruto.UseKunai();
            naruto.ExclusiveSkill();
            Console.ReadKey();
        }
    }

    public abstract class KonohaNinja
    {
        protected string name;
        public KonohaNinja(string name)
        {
            this.name = name;
        }
        public void UseKunai()
        {
            Console.WriteLine("{0}使用了苦无", name);
        }
        public abstract void ExclusiveSkill();

    }

    public class Shikamaru : KonohaNinja
    {
        public Shikamaru(string name) : base(name)
        {

        }
        public override void ExclusiveSkill()
        {
            Console.WriteLine("{0}使用了影子绞首术", name);
        }
    }

    public class Naruto : KonohaNinja
    {
        public Naruto(string name) : base(name)
        {
        }

        public override void ExclusiveSkill()
        {
            Console.WriteLine("{0}使用了风遁螺旋丸手里剑", name);
        }
    }

    public class Kakashi : KonohaNinja
    {
        public Kakashi(string name) : base(name)
        {
        }

        public override void ExclusiveSkill()
        {
            Console.WriteLine("{0}使用了雷切", name);
        }
    }

    public interface CreateNinja
    {
        KonohaNinja CreateObject();
    }

    public class CreateShikamaru : CreateNinja
    {
        public KonohaNinja CreateObject()
        {
            return new Shikamaru("奈良鹿丸");
        }
    }

    public class CreateNaruto : CreateNinja
    {
        public KonohaNinja CreateObject()
        {
            return new Naruto("漩涡鸣人");
        }
    }

    public class CreateKakashi : CreateNinja
    {
        public KonohaNinja CreateObject()
        {
            return new Kakashi("卡卡西");
        }
    }
}

运行结果

在这里插入图片描述
如果想把第二回合的人物换成卡卡西出场,只需要将 CreateNinja narutoFact = new CreateNaruto(); 换成 CreateNinja narutoFact = new CreateKakashi ();即可.

    class Program
    {
        static void Main(string[] args)
        {

            Console.WriteLine("=========与飞段角都的战斗==========");
            CreateNinja shikamaruFact = new CreateShikamaru();//需要客户端确定生产哪个对象
            KonohaNinja shikamaru = shikamaruFact.CreateObject();
            Console.WriteLine("=========第一回合==========");
            shikamaru.UseKunai();
            shikamaru.ExclusiveSkill();
            CreateNinja narutoFact = new CreateKakashi();//这里替换了
            KonohaNinja naruto = narutoFact.CreateObject();
            Console.WriteLine("=========第二回合==========");
            naruto.UseKunai();
            naruto.ExclusiveSkill();
            Console.ReadKey();
        }
    }

在这里插入图片描述
PS:这个例子并不是很贴切,但整体的构架思想是这样的,使用工厂模式我们创建的对象一般是可重复的,而不是独有的,可以将上述人物类进一步抽象,比如 近程忍者,远程忍者,医疗忍者等等, 这时候创建工厂,就不是只针对一个特定的忍者创建的工厂了,而是一个类型忍者的工厂.用工厂模式,从工作量来看并未减轻太多,可能还有增加,而且创建哪种对象的逻辑也迁移到了客户端,但工厂模式完备了开放封闭的原则,将 创建对象与使用对象解耦合.如果要增加对象只需要增加该对象,和对应的对象工厂,不影响其他的类使用.工厂模式去代替直接实例化对象是为了可复用,并且可以实现模块间的解耦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值