工厂方法模式

上一篇 / 下一篇  2009-08-28 14:50:20 / 个人分类:.NET设计模式

工厂方法模式是设计模式中应用最为广泛的一种。

在面向对象的编程中,对象的创建工作非常简单,对象的创建时机却非常重要。工厂方法模式要解决的就是对象的创建时机问题。

我们可以想象一下现实中的例子:男人跟女人。他们都有吃饭、工作、睡觉这些动作,但是这些动作的具体实现肯定因性别不同而不同,比如女人吃饭一般都比较满,而男人会快一些。现在我们要在客户端生成一个人,然后执行这个人的Eat(),Work(),Sleep()这些动作,可能是在某些情况下我们会生成一个男人,其他情况下生成一个女人。怎么做呢,我们首先想到的可能是先创建两个男人、女人类:

    public class Man
    {
        void Eat()
        {
            Console.WriteLine("Man is eating!");
        }

        void Work()
        {
            Console.WriteLine("Man is working!");
        }

        void Sleep()
        {
            Console.WriteLine("Man is sleeping!");
        }
    }
    public class Woman
    {
        void Eat()
        {
            Console.WriteLine("Woman is eating!");
        }

        void Work()
        {
            Console.WriteLine("Woman is working!");
        }

        void Sleep()
        {
            Console.WriteLine("Woman is sleeping!");
        }
    }

然后在客户端可以这样:

        static void Main(string[] args)
        {
            Man man= new Man();
            man.Eat();
        }

但是,如果我们现在不想构造男人了,而是要构造一个女人,就要把上面所有这种代码都改成:

        static void Main(string[] args)
        {
            Woman womman = new Woman();
            womman.Eat();
        }

这显然是不合适的,现在我们引入工厂方法模式,这个模式涉及到的角色有:

1. 一个抽象的产品接口,工厂创建的所有产品都实现了这个接口,在本例子中我们称之为Human接口

    public interface Human
    {
        void Eat();
        void Work();
        void Sleep();
    }

2. 具体的产品类,在本例子中,是Man跟Woman

    public class Man : Human
    {
        void Human.Eat()
        {
            Console.WriteLine("Man is eating!");
        }

        void Human.Work()
        {
            Console.WriteLine("Man is working!");
        }

        void Human.Sleep()
        {
            Console.WriteLine("Man is sleeping!");
        }
    }
    public class Woman : Human
    {
        void Human.Eat()
        {
            Console.WriteLine("Woman is eating!");
        }

        void Human.Work()
        {
            Console.WriteLine("Woman is working!");
        }

        void Human.Sleep()
        {
            Console.WriteLine("Woman is sleeping!");
        }
    }

3. 抽象工厂接口,它定义了所有的具体工厂必须实现的接口,在本例子中,我们可以称之为PeopleCreator

    public interface PeopleCreator
    {
        Human Create();
    }

4. 具体的工厂,它返回的是一个具体的产品类

    public class ManCreator:PeopleCreator
    {
        Human PeopleCreator.Create()
        {
            return new Man();
        }
    }

    public class WomanCreator : PeopleCreator
    {
        Human PeopleCreator.Create()
        {
            return new Woman();
        }
    }

然后我们客户端可以这样写:

        static void Main(string[] args)
        {
            PeopleCreator creator = new ManCreator();
            Human people = creator.Create();
            people.Work();
        }

如果要生成女人的话,我们只要改将PeopleCreator creator = new ManCreator();改为      PeopleCreator creator = new WomanCreator();就可以了。

到这里,有的人可能疑问,如果这样的话,我们为什么不这样写呢:

        static void Main(string[] args)
        {
            Human people = new Man();
            people.Work();
        }

这样在改为女人的时候,也是只要把Human people = new Man();改为Human people = new Womman();就可以了啊。

其实我是这样认为的,有工厂方法模式主要的是没有在客户端牵涉到具体产品类的创建,而是将这些具体产品类的创建放在了相应的具体工厂里了,这样有一个好处,就是如果在实例化一个具体产品类的时候(在本例中,就是在调用Human people = creator.Create()的时候),我现在要根据另外一个类的实例的情况来做一些特殊处理,比如决定是否真的返回一个Human实例还是返回NULL,或为这个Human实例初始化一些属性等。这是后如果是用工厂方法模式的话,我们就可以将 PeopleCreator改一下:

    public interface PeopleCreator
    {
        Human Create(Context context);
    }


再将具体工厂改一下:

    public class ManCreator:PeopleCreator
    {
        Human PeopleCreator.Create(Context context)
        {
            if (context怎么样)
            {
                Man man = new Man();
                为man做一些处理
                return man;
            }
        }
    }

这就是将产品对象的创建跟客户端代码解耦合的好处。

上一篇我们看了抽象工厂模式,这两种模式都有四个参与对象:抽象工厂,具体工厂,抽象产品,具体产品。但不同的是抽象工厂模式中,工厂生产的是一个系列的产品,就是说一个具体工厂生产这个系列产品的某种类型,另一个具体工厂生产这个系列产品的另一种类型。而工厂方法模式则只是关于一个产品的多个类型的。


TAG:

 

评分:0

我来说两句

Open Toolbar