• 工厂模式


    什么是工厂模式?

           类比生活中的概念,当我们需要打电话的时候,我们需要一部手机,我们通常会选择直接去卖手机的实体店买。但在程序设计中,当我们需要调用一个类(PhoneA或PhoneB)的方法的时候,我们往往还要关心他是怎么new出来的(见代码段1)。这就好比我们自己还要去工厂里面告诉他们你要怎么生产出一部我需要的手机。而我们只关心他能不能打电话,你怎么做的关我屁事。所以这就有了工厂模式。工厂模式其实就是抽象出一个工厂,我需要什么手机,去哪个工厂买就行了。我不必关心他的制作过程,你只要能生产我要的功能的手机就行。所以我们需要引入简单工厂,让我们不用再关心手机怎么生产的,具体代码的实现见代码段2.

    public class Customer
    {
        public void CallSomeOne(){
            PhoneA p1 = new PhoneA();
            p1.Call();
        }
    }
    public class PhoneA
    {
        public void Call(){}
    }
    public class PhoneB
    {
        public void Call(){}
    }

    代码段1 :通常的调用类方法的方式

    using System;
    namespace Example1
    {
        public interface IProduct { }
        public class PhoneA : IProduct { }
        public class PhoneB : IProduct { }
    
        public class Factory
        {
            public IProduct Create()
            {
                // 工厂决定到底实例化哪个子类。
                return new PhonetA ();
            }
        }
    }
    
    
    using System;
    namespace Example1
    {
        public enum Category
        {
            A,
            B
        }
    
        public static class ProductFactory
        {
            public static IProduct Create(Category category)
            {
                switch (category)
                {
                    case Category.A:
                        return new PhoneA();
                    case Category.B:
                        return new PhoneB();
                    default:
                        throw new NotSupportedException();
                }
            }
        }
    }

    代码段2:简单工厂模式的实现

     

    [TestMethod]
            public void Test()
            {
                Factory factory = new Factory();
                IProduct phone = factory.Create();    
                Assert.AreEqual<Type>(phone.GetType(), typeof(PhoneA)); 
            }

    代码段3:对简单工厂模式的测试

    新的问题

             其实刚刚也提到了,我们只要一只能打电话的手机,我就想去实体店买一下,我才不关心是哪个工厂生产的呢~而在简单工厂中,我们还需要关心是哪个工厂生产的(见代码段3)。所以我们在代码里面实现一个实体店,这样我们就不用关心到底是哪个工厂生产的啦。所以我们需要引入抽象工厂,这样我们只需要跟实体店打交道,不要再关心要去找什么工厂拿手机了。具体的实现见代码段4.我们可以利用配置文件实现对工厂的选择,对产品的选择,因为本文不想引入其他的概念,这里就不讨论了。

    namespace Example2
    {
        /// <summary>
        /// 抽象的工厂类型特性描述
        /// </summary>
        public interface IFactory
        {
            IProduct Create();  //  每个工厂所需要具有的工厂方法——创建产品
        }
    
        /// <summary>
        /// 实体工厂类型
        /// </summary>
        public class FactoryA : IFactory
        {
            public IProduct Create()
            {
                return new PhoneA();
            }
        }
    
        /// <summary>
        /// 实体工厂类型
        /// </summary>
        public class FactoryB : IFactory
        {
            public IProduct Create()
            {
                return new PhoneB();
            }
        }
    }
    
    
    using System;
    using System.Diagnostics;
    namespace Example2
    {
        class Client
        {
            public void SomeMethod()
            {
                IFactory factory = new FactoryA();   // 获得了抽象Factory的同时,与FactoryA产生依赖;
                IProduct Phone = factory.Create(); // 后续操作仅以来抽象的IFactory和IProduct完成
                // ...
            }
    
            private IFactory factory;
    
            public Client(IFactory factory)     // 将IFactory通过Setter方式注入
            {
                if (factory == null) throw new ArgumentNullException("factory");
                this.factory = factory;
            }
    
            public void AnotherMethod()
            {
                IProduct Phone = factory.Create();
                // ... ...
            }
        }
    
    
    }

    代码段4 抽象工厂的实现

     

    小结

    1、工厂方法模式注重的是整体对象的创建方法

    2、工厂方法的意图非常明确,它把类的实例化过程延迟到子类,将new()的工作交给工厂 完成。同时,增加一个抽象的工厂定义,解决一系列具有统一通用工厂方法的实体工厂问题。 在.NET 平台中,我们可以借助配置、泛型和委托的方法在实现经典模式目的的同时,获得工厂类型与客户程序间更加松散的构造过程。

    参考书《设计模式——基于C#的工程化实现及扩展》

  • 相关阅读:
    java中给集合快速取值最大值和最小值
    Mybatis.xml文件中大于小于等于
    Validate表单验证
    更新了svn 后,某个文件多了几个副本如:xxx.r1 xxx.r3 xxx.mine等,正常文件名xxx
    Oracle监听出现的问题总结,以及解决办法
    oracle三个网络配置文件(listener.ora、tnsname.ora、sqlnet.ora)的作用
    Lucene提供的条件判断查询
    Lucene 单域多条件查询
    lucene自定义过滤器
    luke使用
  • 原文地址:https://www.cnblogs.com/kissazi2/p/3050232.html
Copyright © 2020-2023  润新知