工厂模式之工厂方法模式

1. 引入html

  当前社会分工愈来愈细,愈来愈专业化,各种产品的建立有专门的工厂生产,极大缩短了产品生产周期,提升了生产效率。同理,在软件开发中,软件对象的生产由具体的工厂进行建立,客户能够随意的增长或删除产品对象对其余产品都不会有影响也不须要从新编译。ide

2. 定义 学习

  工厂方法模式,是定义一个用于建立产品对象的工厂接口,将产品对象的实际建立工做推迟到具体子工厂类中。知足了建立型模式中所要求的“建立与使用分离”的特色。spa

  若是要建立的产品很少,只须要一个工厂便可完成,这种模式称为“简单工厂模式”,该模式的缺点是,新增产品时违背了面向对象的“开闭原则”。code

3. 工厂方法实现计算器功能htm

  之前面博客工厂模式之简单工厂中提出的实现计算器功能为例,用工厂方法进行实现,结构图以下图1所示,代码以下:对象

  简单工厂模式中分支与工厂类耦合,须要增长新的运算类时,须要在工厂方法中的switch..case中添加判断条件,根据依赖倒转原则,将工厂类与运算进行解耦,所以,抽象出一个接口,接口中只有一个方法,建立抽象产品的工厂方法。以后,全部要生产具体类的工厂去实现这个接口。这样简单工厂模式的工厂类,变成了一个抽象工厂接口和多个生产类的具体工厂。此时,简单工厂模式的工厂类变成一个工厂抽象接口和多个具体生成对象的工厂。blog

 

class Operate
    {
        private double _num1;
        private double _num2;
        public double num1
        {
            get { return num1; }
            set { num1 = _num1; }
        }
        public double num2
        {
            get { return num2; }
            set { num2 = _num2; }
        }
        public virtual double getResult(double num1, double num2)
        {
            double result = 0.0;
            return result;
        }
    }
    class Add : Operate
    {

        public override double getResult(double n1, double n2)
        {
            return n1 + n2;
        }
    }
    class Sub : Operate
    {

        public override double getResult(double n1, double n2)
        {
            return n1 - n2;
        }
    }
    class Multiply : Operate
    {
        public override double getResult(double n1, double n2)
        {
            return n1 * n2;
        }
    }
    class Divide : Operate
    {
        public override double getResult(double n1, double n2)
        {
            if (n2 == 0)
                throw new Exception("除数不能为0");
            return n1 / n2;
        }
    }
interface IFactory
    {
        Operate createOperate();
    }
    class AddFactory:IFactory
    {
        public Operate createOperate()
        {
           return new Add();
        }
    }
    class SubFactory : IFactory
    {
        public Operate createOperate()
        {
            return new Sub();
        }
    }
    class MultiplyFactory : IFactory
    {
        public Operate createOperate()
        {
            return new Multiply();
        }
    }
    class DivideFactory : IFactory
    {
        public Operate createOperate()
        {
            return new Divide();
        }
    }
 class Program
    {
        static void Main(string[] args)
        {
            IFactory operateFactory = new AddFactory();
            Operate ope = operateFactory.createOperate();
            double result = ope.getResult(1.0,2.0);
            Console.WriteLine("{0}",result);
            Console.Read();
        }
    }

   在工厂方法模式中,选择用哪一个工厂实现运算类,由原来的工厂类内部转移到客户端判别。继承

4.情景实现接口

  情景介绍:某同窗“学雷锋”以学习雷锋的名义在医院作义工(打扫、洗衣、买饭),在他生病的时候,其余人以一样的名义代替他去,首先使用简单工厂模式实现。

  分析发现,该场景中能够把“学雷锋”和其余人抽象出一个“雷锋”类,拥有打扫、洗衣、买饭的方法,代码以下:

  class LeiFeng
    {
        public void Sweep()
        {
            Console.WriteLine("I am sweeping");
        }
        public void Wash()
        {
            Console.WriteLine("I am washing");
        }
        public void Cook()
        {
            Console.WriteLine("I am cooking");
        }
    }
  class Student:LeiFeng
    {
    }
  static void Main(string[] args)
        {
            LeiFeng lf=new Student();
            lf.Cook();
            lf.Sweep();
            lf.Wash();
            Console.WriteLine("Hello World!");
        }

  然而,若是有多个学生学雷锋作好事时,须要进行屡次实例化,会形成大量重复代码以及建立对象的资源消耗。而对医院病人来讲,不须要知道具体的对象是谁,只须要知道是学雷锋的人帮忙就好。此外,有其余社会人士“志愿者”学雷锋作好事,须要再新建一个类继承LieFeng,由雷锋工厂决定实例化谁,这是简单工厂模式的实现,具体以下:

   class SimpleFactory
    {
        public static LeiFeng createObject(string type)
        {
            LeiFeng result = null;
            switch (type)
            {
                case "学雷锋的大学生":
                    result = new Student(); break;
                case "社区志愿者":
                    result=new Volunteer();break;
            }
            return result;
        }
    }
  class Volunteer:LeiFeng
    {

    }
    static void Main(string[] args)
        {
          LeiFeng stud = SimpleFactory.createObject("学雷锋的大学生");
            stud.Sweep();
            LeiFeng stud2 = SimpleFactory.createObject("社区志愿者");
            stud2.Cook();
            Console.WriteLine("Hello World!");
        }

  上述实现为简单工厂模式,将其更改成工厂方法模式,所有代码以下:

interface SimpleFactory
    {
        LeiFeng CreateLeiFeng();
    } 
class StudengFactory:SimpleFactory
    {
        public LeiFeng CreateLeiFeng()
        {
            return new Student();
        }
    }
    class VolunteerFactory
    {
        public LeiFeng CreateLeiFeng()
        {
            return new Volunteer();
        }
    }
class LeiFeng
    {
        public void Sweep()
        {
            Console.WriteLine("I am sweeping");
        }
        public void Wash()
        {
            Console.WriteLine("I am washing");
        }
        public void Cook()
        {
            Console.WriteLine("I am cooking");
        }
    }
 class Student:LeiFeng
    {

    }
class Volunteer:LeiFeng
    {

    }
static void Main(string[] args)
        {
            SimpleFactory sf=new StudengFactory();
            LeiFeng studeng = sf.CreateLeiFeng();
            studeng.Sweep();
            studeng.Wash();
            Console.WriteLine("Hello World!");
        }
View Code

5. 总结

  工厂方法模式主要由4部分组成:

  • 抽象工厂角色。是工厂方法模式的核心,与应用程序无关,是具体工厂角色必须实现的接口或必须继承的父类。(IFactory)
  •  具体工厂角色。包含和具体逻辑有关的代码。客户端调用,返回产品实例。(如AddFactory)
  • 抽象产品角色。是产品接口(如Operation)。
  • 具体产品角色。具体工厂角色所建立的对象就是此角色的实例(如AddOperate类)。

  简单工厂模式和工厂方法模式的区别:

        简单工厂模式中工厂类中包含必要的逻辑判断,根据客户说的选择条件实例化相关类,客户端与具体产品没有依赖。而工厂方法模式实现时,客户端须要决定实例化哪一个工厂来实现运算类,可是逻辑判断在客户端进行。

       工厂方法模式是简单工厂模式的衍生,解决了简单工厂模式违反“开闭”原则的问题,并实现了可扩展,可以解决更复杂的层次结构,可用于产品结果复杂的场合。

相关文章
相关标签/搜索