简单工厂模式&工厂方法模式&抽象工厂模式的区别及优缺点及使用场景

简单工厂模式&工厂方法模式&抽象工厂模式的区别及优缺点及使用场景


工厂模式是设计模式中比较简单的一个设计模式,但很多地方都用到了工厂模式,(如解析xml中,jdbc连接数据库等)利用好工厂模式对程序的设计很有用处。

工厂模式在一些设计模式的书中分为简单工厂模式,工厂方法模式和抽象工厂模式三类。也有把工厂方法模式划分到抽象工厂模式的,认为工厂方法是抽象工厂模式的特例的一种,就是只有一个要实现的产品接口。
在这里插入图片描述

简单工厂

普通简单工厂

就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。首先看下关系图

举个获取鼠标信息例子,我们有个例子。

  1. 创建获取鼠标信息共同接口
   public class LenoveMouse : IMouse
    {
        public string GetMouseInfo()
        {
            return "联想品牌鼠标";
        }
    }
  1. 联想鼠标实现类
 public string GetMouseInfo()
        {
            return "联想品牌鼠标";
        }

3.惠普鼠标实现类

 public class HPMouse : IMouse
   {
       public string GetMouseInfo()
       {
           return "惠普品牌鼠标";
       }
   }
  1. 鼠标工厂类
  public class MouseFactory
    {
        /// <param name="type">0 代码惠普鼠标 1 代码联想鼠标</param>
        /// <returns></returns>
        public IMouse GetMouse(int type)
        {
            if (type == 0)
            {
                return new HPMouse();
            }
            else if (type == 1)
            {
                return new LenoveMouse();
            }
            else {

                Console.WriteLine("请输入正确类型!");
                return null;
            }
        }
    }
  1. 控制台调用
 class Program
    {
        static void Main(string[] args)
        {
            MouseFactory mouseFactory = new MouseFactory();
           string mouseInfo1 = mouseFactory.GetMouse(0).GetMouseInfo();
            Console.WriteLine(mouseInfo1);
           // 输出:惠普品牌鼠标
            string mouseInfo2 = mouseFactory.GetMouse(1).GetMouseInfo();
            Console.WriteLine(mouseInfo2);
           //输出:联想品牌鼠标
        }
    }

多方法简单工厂

是对普通工厂方法模式的改进,在普通工厂方法模式中,如果传递的类型出错,则不能正确创建对象,而多个工厂方法模式是提供多个工厂方法,分别创建对象。关系图:
在这里插入图片描述
工厂类修改

 public class MouseFactory
    {

        public IMouse GetHPMouse()
        {
            return new HPMouse();
        }

        public IMouse GetMouse()
        {
            return new LenoveMouse();
        }

    }

控制台调用修改

   class Program
    {
        static void Main(string[] args)
        {
            MouseFactory mouseFactory = new MouseFactory();
            string mouseInfo1 = mouseFactory.GetHPMouse().GetMouseInfo();
            //输出惠普鼠标品牌
            Console.WriteLine(mouseInfo1);          
            string mouseInfo2 = mouseFactory.GetLenoveMouse().GetMouseInfo();
            //输出联想鼠标品牌
            Console.WriteLine(mouseInfo2);
            Console.ReadLine();
        }
    }

静态方法简单工厂

将上面的多个工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可。

 public class MouseFactory
    {

        public static IMouse GetHPMouse()
        {
            return new HPMouse();
        }

        public static IMouse GetLenoveMouse()
        {
            return new LenoveMouse();
        }

    }

控制台调用

  class Program
    {
        static void Main(string[] args)
        {          
            string mouseInfo1 = MouseFactory.GetHPMouse().GetMouseInfo();
            //输出惠普鼠标品牌
            Console.WriteLine(mouseInfo1);          
            string mouseInfo2 = MouseFactory.GetLenoveMouse().GetMouseInfo();
            //输出联想鼠标品牌
            Console.WriteLine(mouseInfo2);
            Console.ReadLine();
        }
    }

工厂方法模式

简单工厂模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改。假如增加其他品牌鼠标,工厂类需要修改,如何解决?就用到工厂方法模式,创建一个工厂接口和创建多个工厂实现类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。
在这里插入图片描述
增加Factory接口

  public interface Factory
    {
        /// <summary>
        /// 获取鼠标工厂
        /// </summary>
        /// <returns></returns>
         IMouse GetMouseFactory();

    }

添加惠普鼠标工厂实现类

 public class HPMouseFactory:Factory
    {
        public IMouse GetMouseFactory()
        {
            return new HPMouse();
        }
    }

添加联想鼠标工厂实现类


    public class LenoveMouseFactory : Factory
    {
        public IMouse GetMouseFactory()
        {
            return new LenoveMouse();
        }
    }

控制台调用

在这里插入代码片
class Program
{
    static void Main(string[] args)
    {
        //实例化惠普鼠标工厂
        Factory factory = new HPMouseFactory();
        string mouseInfo1 = factory.GetMouseFactory().GetMouseInfo();
        //输出惠普鼠标品牌
        Console.WriteLine(mouseInfo1);
        //实例化联想鼠标工厂
        Factory factory2 = new LenoveMouseFactory();
        string mouseInfo2 = factory2.GetMouseFactory().GetMouseInfo();
        //输出联想鼠标品牌
        Console.WriteLine(mouseInfo2);
        Console.ReadLine();
    }
}
工厂方法模式中我们把生成产品类的时间延迟,就是通过对应的工厂类来生成对应的产品类,在这里我们就可以实现“开发-封闭”原则,无论加多少产品类,我们都不用修改原来类中的代码,而是通过增加工厂类来实现。但是这还是有缺点的,如果添加键盘产品,就需要添加键盘工厂类。假如我们要实现的产品接口不止一个,也就是有多个产品接口,不同产品接口有对应的产品族。什么是产品族呢?简单的理解就是,不同厂家的不仅有鼠标,还有键盘,音响,笔记本可以组成一个产品族。对于这种情况我们可以采用抽象工厂模式。

抽象工厂模式

最后我们新增一个键盘产品类说明抽象工厂模式
在这里插入图片描述

  1. 创建获取鼠标信息共同接口
   public class LenoveMouse : IMouse
    {
        public string GetMouseInfo()
        {
            return "联想品牌鼠标";
        }
    }
  1. 联想鼠标实现类
 public string GetMouseInfo()
        {
            return "联想品牌鼠标";
        }

3.惠普鼠标实现类

  public class HPMouse : IMouse
    {
        public string GetMouseInfo()
        {
            return "惠普品牌鼠标";
        }
    }
    

4.创建键盘接口类

 public interface IKeyboard
    {
         string GetKeyboardInfo();    
    }

5.创建惠普键盘实现类

  public class HPKeyboard : IKeyboard
    {
        public string GetKeyboardInfo()
        {
            return "惠普键盘";
        }
    }

6.创建联想键盘实现类


    public class LenoveKeyboard : IKeyboard
    {
        public string GetKeyboardInfo()
        {
            return "联想键盘";
        }
    }

7.创建工厂接口类提供获取鼠标鼠标和键盘接口

 public interface Factory
    {
        /// <summary>
        /// 获取鼠标工厂
        /// </summary>
        /// <returns></returns>
         IMouse GetMouseFactory();
        /// <summary>
        /// 获取键盘工厂
        /// </summary>
        /// <returns></returns>
        IKeyboard GetKeyboardFactory();

    }

8.创建联想工厂实现类

  public class LenoveFactory : Factory
    {
        public IKeyboard GetKeyboardFactory()
        {
            return new LenoveKeyboard();
        }

        public IMouse GetMouseFactory()
        {
            return new LenoveMouse();
        }
    }

9.创建惠普工厂实现类型

  public class HPFactory:Factory
    {
        public IKeyboard GetKeyboardFactory()
        {
            return new HPKeyboard();
        }

        public IMouse GetMouseFactory()
        {
            return new HPMouse();
        }
    }

控制台调用

   class Program
    {
        static void Main(string[] args)
        {
            //实例化惠普鼠标工厂
            Factory factory = new HPFactory();
            string mouseInfo1 = factory.GetMouseFactory().GetMouseInfo();
            string keyboard1 = factory.GetKeyboardFactory().GetKeyboardInfo();

            //输出惠普鼠标品牌
            Console.WriteLine(mouseInfo1);
            //输出惠普键盘
            Console.WriteLine(keyboard1);
            //实例化联想鼠标工厂
            Factory factory2 = new LenoveFactory();
            string mouseInfo2 = factory2.GetMouseFactory().GetMouseInfo();
            //输出联想鼠标品牌
            Console.WriteLine(mouseInfo2);
            //输出联想键盘品牌
            string keyboard2= factory2.GetKeyboardFactory().GetKeyboardInfo();
            Console.ReadLine();
        }
    }

抽象工厂模式中我们可以定义实现不止一个接口,一个工厂也可以生成不止一个产品类,抽象工厂模式较好的实现了“开放-封闭”原则,是三个模式中较为抽象,并具一般性的模式。我们在使用中要注意使用抽象工厂模式的条件。
无论是工厂模式增加代码复制度,有没有一种办法,不需要创建工厂,也能解决代码以后变动修改少方法。答案是有的,通过(ioc)控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。也可以说,(di)依赖被注入到对象中。
后续继续讲解如何使ioc优化程序。
案例代码下载
由于水平有限,文章中难免有错误的地方,欢迎指出错误或不足之处,共同进步。欢迎转载,转载时请注明出处,谢谢。 ——by EricDrSun

  • 37
    点赞
  • 150
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值