Fork me on GitHub

设计模式系列一创建型模式之(简单工厂VS工厂方法)

1、简单工厂简介

诞生背景:在我们平常编程当中,经常会使用new进行实例化一个对象,此时该类完全依赖于该对象,专业术语来说就是耦合度高。当需求发生变化时我们不得不去修改此类的源码,造成整个系统难以维护!然而面向对象(oo)一个很重要的原则(封装变化)就可以解决这样一个问题;那既然要封装变化,自然要找到改变的代码,然后把改变的代码用类进行封装。这样一个思路就引出了简单工厂模式。

定义:简单工厂模式又叫静态工厂模式,顾名思义,它是用来实例化对象类的静态类。

 

2、简单工厂实例

 

 /// <summary>
    /// 动物抽象类
    /// </summary>
    public abstract class Animal
    {
        public abstract void Eat();
        public abstract void Call();
    }

    public class Cat : Animal
    {

        public override void Eat()
        {
            Console.WriteLine("Fish");
        }

        public override void Call()
        {
            Console.WriteLine("miao...");
        }
    }

    public class Dog : Animal
    {

        public override void Eat()
        {
            Console.WriteLine("Shit");
        }

        public override void Call()
        {
            Console.WriteLine("wang...");
        }
    }
    /// <summary>
    /// 简单工厂类
    /// </summary>
    public class AnimalSimpleFactory
    {
        public static Animal CreateAnimal(string type)
        {
            Animal animal = null;
            switch (type)
            {
                case "cat": animal = new Cat(); break;
                case "dog": animal = new Dog(); break;
                default: break;
            }
            return animal;
        }
    }

客户端调用方式:

    static void Main(string[] args)
        {
            Animal animal = AnimalSimpleFactory.CreateAnimal("dog");
            animal.Eat();
            animal.Call();
            Console.ReadLine();
        }

解析:AnimalSimpleFactory中的CreateAnimal方法负责具体Animal的生产,从而降低了对象之间的耦合度;但是,如果我们想要新加一类动物的话,我们还是需要修改工厂类中的代码(新加case语句判断)同样还是违背了OCP原则,同时也会造成工厂类中实现逻辑过于复杂,这也正是简单工厂模式的缺点所在!

3、工厂方法模式

诞生背景:为了解决简单工厂模式还是不能完全满足OCP原则的问题便引发了对工厂方法模式的思考!

实现方式:简单工厂只有一个(对于一个项目或者一个独立模块而言)工厂类,而工厂方法模式的实现是把具体对象的创建推迟到子类中,此时工厂类不再负责所有对象的创建而是只发出口令把创建对象的过程转交到其子类中;这样再扩展的时候不需要再修改工厂类的逻辑,于是便完全满足了OCP!

4、工厂方法模式实例

 

  /// <summary>
    /// 动物抽象类
    /// </summary>
    public abstract class Animal
    {
        public abstract void Eat();
        public abstract void Call();
    }

    public class Cat : Animal
    {
        public override void Eat()
        {
            Console.WriteLine("Fish");
        }

        public override void Call()
        {
            Console.WriteLine("miao...");
        }
    }

    public class Dog : Animal
    {
        public override void Eat()
        {
            Console.WriteLine("Shit");
        }

        public override void Call()
        {
            Console.WriteLine("wang...");
        }
    }
    /// <summary>
    /// 抽象工厂类
    /// </summary>
    public abstract class AnimalCreater
    {
        //工厂方法
        public abstract Animal CreateAnimal();
    }

    public class CatCreater : AnimalCreater
    {
        public override Animal CreateAnimal()
        {
            return new Cat();
        }
    }
    public class DogCreater : AnimalCreater
    {
        public override Animal CreateAnimal()
        {
            return new Dog();
        }
    }

客户端调用方式:

     static void Main(string[] args)
        {
            AnimalCreater catCreater = new CatCreater();
            Animal cat = catCreater.CreateAnimal();
            cat.Eat();
            cat.Call();
            AnimalCreater dogCreater = new DogCreater();
            Animal dog = dogCreater.CreateAnimal();
            dog.Eat();
            dog.Call();
            Console.ReadLine();
        }

解析:如果要再添加新的动物时,就可以使用多态来实现,对于抽象工厂类和具体对象创建类中的代码都无需做任何改动;我们只需要新定义一个动物类和动物创建类就OK!

5、简单工厂模式与工厂方法模式对比总结

从以上对两种模式的介绍可以了解到,工厂方法模式是为了克服简单工厂模式的缺点(主要是为了满足OCP)而设计出来的。但是,工厂方法模式就一定比简单工厂模式好呢?笔者的答案是不一定 !

1. 结构复杂度
从这个角度比较,显然简单工厂模式要占优。简单工厂模式只需一个工厂类,而工厂方法模式的工厂类随着产品类个数增加而增加,这无疑会使类的个数越来越多,从而增加了结构的复杂程度。

2.代码复杂度
代码复杂度和结构复杂度是一对矛盾,既然简单工厂模式在结构方面相对简洁,那么它在代码方面肯定是比工厂方法模式复杂的了。简单工厂模式的工厂类随着产品类的增加需要增加很多方法(或代码),而工厂方法模式每个具体工厂类只完成单一任务,代码简洁。

3.客户端编程难度
工厂方法模式虽然满足了OCP,但是在客户端编码中需要对工厂类进行实例化。而简单工厂模式中就是个静态方法,在客户端无需实例化,这无疑是个吸引人的优点。

 

注:两者各有千秋,仁者见仁,智者见智!

 

posted @ 2014-08-14 12:52  迁梦余光  阅读(301)  评论(0编辑  收藏  举报