简单工厂、工厂方法和抽象工厂的学习笔记

简单工厂

理解:简单工厂模式的工厂类一般是使用静态方法,通过接收的参数不同来返回不同的对象的实例,不修改代码的话,是无法扩展的。 


先定义产品类,它们需要实现同一接口或继承自同一抽象类。

    //产品接口(或抽象类)
    public interface IClassDo
    {
        
void doSomething();
    }

    
public class Class1 : IClassDo
    {
        
public void doSomething()
        {
            Console.WriteLine(
"class1");
        }
    }

    
public class Class2 : IClassDo
    {
        
public void doSomething()
        {
            Console.WriteLine(
"class2");
        }
    }

设计简单工厂:

    public class SimpleFactory
    {
        
public IClassDo factory(string type)
        {
            
switch (type)
            {
                
case "class1":
                    
return new Class1();
                
case "class2":
                    
return new Class2();
                
default:
                    
throw new Exception("error");
            }
        }
    }

 调用简单工厂:

            //调用简单工厂
            IClassDo simpleFactoryClassDo = new SimpleFactory().factory("class1");
            simpleFactoryClassDo.doSomething();

 工厂方法

理解:工厂方法模式是针对每一种产品提供一个工厂类,通过不同的工厂实例来创建不同的产品实例。在同一等级结构中,支持增加任意产品。

产品类设计同“简单工厂”这里就不赘述了。

设计工厂方法:

    public abstract class FactoryMethod
    {
        
public abstract IClassDo factory();
    }

    
public class FactoryMethodClass1 : FactoryMethod
    {
        
public override IClassDo factory()
        {
            
return new Class1();
        }
    }

    
public class FactoryMethodClass2 : FactoryMethod
    {
        
public override IClassDo factory()
        {
            
return new Class2();
        }
    }

 调用工厂方法:

            //调用工厂方法
            FactoryMethod factoryMethod = new FactoryMethodClass1();
            IClassDo factoryMethodClassDo 
= factoryMethod.factory();
            factoryMethodClassDo.doSomething();

 抽象工厂

理解:工厂方法模式是针对每一种产品提供一个工厂类,通过不同的工厂实例来创建不同的产品实例。在同一等级结构中,支持增加任意产品 。

定义产品族:

    //定义两种产品接口
    public interface ICar
    {
        
void doCar();
    }

    
public interface IBus
    {
        
void doBus();
    }

    
//第一种产品族
    public class Car1 : ICar
    {
        
public void doCar()
        {
            Console.WriteLine(
"car1");
        }
    }

    
public class Bus1 : IBus
    {
        
public void doBus()
        {
            Console.WriteLine(
"bus1");
        }
    }

    
//第二种产品族
    public class Car2 : ICar
    {
        
public void doCar()
        {
            Console.WriteLine(
"car2");
        }
    }

    
public class Bus2 : IBus
    {
        
public void doBus()
        {
            Console.WriteLine(
"bus2");
        }
    }

 设计抽象工厂:

    //定义抽象工厂接口
    public interface IFactory
    {
        ICar carFactory();
        IBus busFactory();
    }

    
//专门生产“1”类产品的工厂
    public class Factory1 : IFactory
    {
        
public ICar carFactory()
        {
            
return new Car1();
        }

        
public IBus busFactory()
        {
            
return new Bus1();
        }
    }

    
//专门生产“2”类产品的工厂
    public class Factory2 : IFactory
    {
        
public ICar carFactory()
        {
            
return new Car2();
        }

        
public IBus busFactory()
        {
            
return new Bus2();
        }
    }

 调用抽象工厂:

            //调用抽象工厂
            IFactory factory = new Factory1();
            IBus bus 
= factory.busFactory();
            bus.doBus();

 代码下载:工厂模式例子.rar

 --------------------------------------------------------------------------------------------------------------------------------------------------

以下是关于工厂模式的一定理论定义和区别:(转自:http://blog.csdn.net/felixit0120/article/details/6691845

简单工厂模式:

简单工厂模式的工厂类一般是使用静态方法,通过接收的参数不同来返回不同的对象的实例,不修改代码的话,是无法扩展的

工厂方法模式

工厂方法模式是针对每一种产品提供一个工厂类,通过不同的工厂实例来创建不同的产品实例。

在同一等级结构中,支持增加任意产品

抽象工厂模式:

抽象工厂模式应对产品族的概念。比如说,每个汽车公司可能要同时生产轿车,火车,客车,那么每一个工厂都要有创建桥车,货车和客车的方法。

应对产品族的概念而生,增加新的产品线很容易,但是无法增加新的产品。

小结:

 工厂模式中,重要的是工厂类,而不是产品类。产品类可以是多种形式,多层继承或者单个类都是可以的。但是要明确的是,工厂模式的接口只会返回一种类型的实例。这是在设计产品类的时候需要注意的,最好是有父类或者共同实现的接口。

使用工厂模式,返回的实例一定是工厂创建的,而不是从其他对象中获取的。

工厂模式返回的实例可以不是新创建的,返回由工厂模式创建好的实例也是可以的。

区别:

简单工厂模式:用来生产同一等级结构中的任意产品。对与增加新的产品,无能为力

工厂模式 :用来生产同一等级结构中的固定产品。(支持增加任意产品)   
抽象工厂 :用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)  

以上三种工厂 方法在等级结构和产品族这两个方向上的支持程度不同。所以要根据情况考虑应该使用哪种方法


FAQ:

1.       工厂方法模式,抽象工厂模式区别:

 工厂方法模式:

一个抽象产品类,可以派生出多个具体产品类。一个抽象工厂类,可以派生出多个具体工厂类。每个具体工厂类只能创建一个具体产品类的实例。

抽象工厂模式:

多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。一个抽象工厂类,可以派生出多个具体工厂类。每个具体工厂类可以创建多个具体产品类的实例。

区别:

工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。

工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。


2.       简单工厂模式,工厂方法模式,抽象工厂模式区别:

简单工厂模式,工厂方法模式和抽象工厂模式都属于创建型设计模式,这三种创建型模式都不需要知道具体类。我们掌握一种思想,就是在创建对象时,需要要容易发生变化的地方给封装起来,来控制变化,以适应客户的变动,项目的扩展。

特点:

简单工厂模式:

专门定义一个类负责创建其他类的实例,被创建的实例通常都具有共同的父类。它又称为静态工厂方法模式。它的实质是由一个工厂类根据传入的参数,动态 决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。在这 个模式中,工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。用户在使用时可以直接根据工 厂类去创建所需的实例。而无需了解这些对象时如何创建以及如何组织的。有利于整个软件体系结构的优化。

工厂方法模式:

工厂方法是粒度很小的设计模式,因为模式的表现只是一个抽象的方法。提前定义用于创建对象的接口,让子类决定实例化具体的某一个类,即在工厂和产品 中间增加接口,工厂不再负责产品的创建,由接口针对不同条件返回具体的类实例,由具体类实例去实现。工厂方法模式是简单工厂模式的衍生,解决了许多简单工 厂模式的问题。首先完全实现”开—闭 原则”,实现了可扩展。其次实现了更复杂的层次结构,可以应用于产品结果复杂的场合。工厂方法模式是对简单工厂模式的抽象。有个抽象的Factory类 (可以是抽象类和接口),这个类将不负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以依次 对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品。这个具体的工厂就负责生产对应的产品。

抽象工厂模式:

抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客 户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中得产品对象。它有多个抽象产品类,每个抽象产品类可以派生出多个具体产品类, 一个抽象工厂类,可以派生出多个具体工厂类,每个具体工厂类可以创建多个具体产品类的实例。

每一种模式都是针对一定问题的解决方案,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式针对的是多个产品等级结构。

优点:

简单工厂模式:

工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅“消费”产品。简单工厂模式 通过这种做法实现了对责任的分割。简单工厂模式能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。通过它。外界可以从直接创建具体产品对象的尴 尬局面中拍拖出来。外界与具体类隔离出来,耦合性低。明确区分了各自的职责和权力,有利于整个软件体系结构的优化。

工厂方法模式:

工厂方法模式是为了克服简单工厂模式的缺点而设计出来的。简单工厂模式的工厂类随着产品类的增加而需要增加很多方法(或代码),而工厂方法模式每个具体工厂类只完成单一任务,代码简洁。工厂方法模式完全满足OCP,即它具有非常良好的扩展性。

抽象工厂模式:

抽象工厂模式主要在于应对“新系列”的需求变化。分离了具体的类,抽象工厂模式帮助你控制一个应用创建的对象的类,因为一个工厂封装创建产品对象的 责任和过程。它将客户和类的实现分离,客户通过他们的抽象接口操纵实例,产品的类名也在具体工厂的实现中被分离,他们不出现在客户代码中。它使得易于交换 产品系列。一个具体工厂类在一个应用中仅出现一次----即在它初始化的时候。这使得改变一个应用的具体工厂变得很容易。它只需改变具体的工厂即可使用不 同的产品配置,这是因为一个抽象工厂创建了一个完整的产品系列,所以整个产品系列会立刻改变。它有利于产品的一致性。当一个系列的产品对象被设计成一起工 作时,一个应用一次只能使用同一个系列中得对象,这一点很重要,而抽象工厂很容易实现这一点。抽象工厂模式有助于这样的团队分工,降低了模块间的耦合性, 提高了团队开发效率。

缺点:

简单工厂模式:

当产品有复杂的多层等级结构时,工厂类只有自己,以不变应万变,就是模式的缺点。因为工厂类集中了所有产品的创建逻辑,一但不能正常工作,整个系统 都要受到影响。系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,有可能造成工厂逻辑过于复杂,违背了“开发—封闭”原则。另外,简单工厂模式通常使用 静态工厂方法,这使得无法由子类继承,造成工厂角色无法形成基于继承的等级结构。

工厂方法模式:

不易于维护,假如某个具体产品类需要进行一定的修改,很可能需要修改对应的工厂类。当同时需要修改多个产品类的时候,对工厂类的修改会变得相当麻烦(对号入座已经是个问题了)

抽象工厂模式:

抽象工厂模式在于难于应付”新对象”的需求变动。难以支持新种类的产品。难以扩展抽象工厂以生产新种类产品。这是因为抽象工厂几乎确定了可以被创建的产品的集合。支持新种类的产品就需要扩展该工厂接口,这将涉及抽象工厂及其所有子类的改变。

适用范围

简单工厂模式:

工厂类负责创建的对象较少,客户只知道传入工厂类的参数,对于如何创建对象不关心。

工厂方法模式:

当一个类不知道它所必须创建对象的类或一个类希望由子类来指定它所创建的对象时,当类将创建对象的职责委托给多个帮助子类中得某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候,可以使用工厂方法模式。

抽象工厂模式:

一个系统不应当依赖于产品类实例何如被创建,组合和表达的细节,这对于所有形态的工厂模式都是重要的。这个系统有多于一个的产品族,而系统只消费其 中某一产品族。同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。系统提供一个产品类的库,所有的产品以同样的接口出现,从 而使客户端不依赖于实现。

其实,无论是简单工厂模式、工厂模式还是抽象工厂模式,它们本质上都是将不变的部分提取出来,将可变的部分留作接口,以达到最大程度上的复用。究竟用哪种设计模式更适合,这要根据具体的业务需求来决定

简单工厂和工厂方法哪个更好 ?

还是工厂模式:)这个模式用得“相当”频繁,问题也比较的,主要是简单工厂,工厂方法,抽象工厂看上去都很相似。

一下整理自我和一个网友的聊天记录:

问题提出:

喻乐(35466616) 12:26:27
吃完饭问个问题,简单工厂和工厂方法那个更好?
喻乐(35466616) 12:28:28
觉得简单工厂也没什么不好,和工厂方法差不多,就是不能继承,每次要创建一个新的对象的时候后要修改其代码,但是工厂模式要创建一个新的对象也需要从抽象类继承,也要添加很多代码,其优越性体现在哪里?

喻乐(35466616) 12:39:40
客户端调用也要指定具体的工厂方法啊
肖鹏(59092922) 12:41:18
客户端虽然指定具体方法,但是方法是抽象的返回的也是接口,而不是具体类。
喻乐(35466616) 12:46:00
返回的应该是实现了接口的具体类啊
肖鹏(59092922) 12:42:44
返回的是接口的实例
喻乐(35466616) 12:47:56
但是简单工厂返回的也是接口的实例阿。
肖鹏(59092922) 12:44:52
简单工厂不能通过继承动态的扩展
喻乐(35466616) 12:49:04
那就往里面加啊:)我觉得添加的代码比工厂方法少啊:)
肖鹏(59092922) 12:46:22
是啊,这样你就动了原来的代码了,设计模式很多时候就是为了,不用修改原有代码适应新的扩展啊
肖鹏(59092922) 12:47:17
简单工厂就像杀鸡刀,工厂方法就像杀牛刀,杀牛刀当然要复杂一些:)
喻乐(35466616) 12:51:17
我觉得这点改动对于这个系统的影响不大。
喻乐(35466616) 12:51:44
其他很多模式的采用是我们大量的缩减了改动的代码:)
肖鹏(59092922) 12:48:20
简单工厂不支持与具体类的平行继承结构,这对于复杂的继承结构很不利
喻乐(35466616) 12:52:45
确实,估计我只考虑了简单结构的情况,当结构一复杂回答来很多不利的影响:)谢谢了
喻乐(35466616) 12:53:57
还是你理解得透彻:)
肖鹏(59092922) 12:50:50
我原来也有这个问题,你看我的博客就能看出来:)
肖鹏(59092922) 12:51:48
有一个现成的例子就是抽象工厂,抽象工厂往往都是用工厂方法来实现的,你想像一下如果用简单工厂能实现吗?

肖鹏(59092922) 12:59:40
我觉得这个疑问很多人都有,因为SimpleFactory是如此“简单易用”:)

 
原文地址:https://www.cnblogs.com/yeagen/p/2173885.html