`
ysa198584
  • 浏览: 36926 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

工厂模式与工厂方法模式

阅读更多
简单工厂模式及实例
简单工厂模式又叫静态工厂模式,顾名思义,它是用来实例化目标类的静态类。下面我主要通过一个简单的实例说明简单工厂及其优点。

比如有个国家的运动员协会,他们是负责登记与注册职业运动员的(就好像我们国家的体育总局,呵呵,无论足球篮球还是乒乓球的运动员都必须在这里注册才能拿到我们国家职业运动员牌照)。一家体育俱乐部(比如篮球的广东宏远,足球的深圳健力宝)想获得球员为自己俱乐部效力,就必须通过这个运动员协会。

根据DIP我们可以设计一个“运动员”接口,“足球运动员”和“篮球运动员”(还有其他运动员)都实现“运动员”这个接口。而“运动员协会”就是一个简单工厂类,它负责实例化“运动员”。我们这里的“俱乐部”就是一个客户端(Client),不同的“俱乐部”就是不同的客户端。具体如下图表示:






对于不同的俱乐部对象(无论是八一还是深圳健力宝),他们都是面向“运动员”接口编程,而不用管是“足球运动员”还是“篮球运动员”,也就是说实现了“运动员”接口的具体类“足球运动员”无需暴露给客户端。这也满足了DIP。但具体的俱乐部(比如足球的深圳健力宝)如何确保自己获取的是自己想要的运动员(健力宝俱乐部需要的当然是足球运动员)呢?这就需要“运动员协会”这一工厂类了。俱乐部通过调用“运动员协会”的具体方法,返回不同的实例。这同时也满足了LoD,也就是“深圳健力宝足球俱乐部”对象不直接与“足球运动员:李毅”对象通信,而是通过他们共同的“朋友”——“国家体育总局”通信。

下面给出各个类的程序,会有助于读者更好的了解笔者之前的介绍。


  Code: [Copy to clipboard]  
运动员.java
public interface 运动员 {       
        public void 跑();
        public void 跳();
}

足球运动员.java
public class 足球运动员 implements 运动员 {

        public void 跑(){
                //跑啊跑
        }
       
        public void 跳(){
                //跳啊跳
        }
}

篮球运动员.java
public class 篮球运动员 implements 运动员 {

        public void 跑(){
                //do nothing
        }
       
        public void 跳(){
                //do nothing
        }
}

体育协会.java
public class 体育协会 {
       
        public static 运动员 注册足球运动员(){
                return new 足球运动员();
        }
       
        public static 运动员 注册篮球运动员(){
                return new 篮球运动员();
        }

}

俱乐部.java
public class 俱乐部 {
        private 运动员 守门员;
        private 运动员 后卫;
        private 运动员 前锋;

        public void test() {
                this.前锋 = 体育协会.注册足球运动员();
                this.后卫 = 体育协会.注册足球运动员();
                this.守门员 = 体育协会.注册足球运动员();
               
                守门员.跑();
                后卫.跳();
        }
}



以上就是简单工厂模式的一个简单实例,读者应该想象不用接口不用工厂而把具体类暴露给客户端的那种混乱情形吧(就好像没了体育总局,各个俱乐部在市场上自己胡乱的寻找仔细需要的运动员),简单工厂就解决了这种混乱。

我们用OCP看看简单工厂,会发现如果要对系统进行扩展的话治需要增加实现产品接口的产品类(上例表现为“足球运动员”,“篮球运动员”类,比如要增加个“乒乓球运动员”类),而无需对原有的产品类进行修改。这咋一看好像满足OCP,但是实际上还是需要修改代码的——对,就是修改工厂类。上例中如果增加“乒乓球运动员”产品类,就必须相应的修改“体育协会”工厂类,增加个“注册乒乓球运动员”方法。所以可以看出,简单工厂模式是不满足OCP的。



工厂方法模式及其实例
谈了简单工厂模式,下面继续谈谈工厂方法模式。前一节的最末点明了简单工厂模式最大的缺点——不完全满足OCP。为了解决这一缺点,设计师们提出了工厂方法模式。工厂方法模式和简单工厂模式最大的不同在于,简单工厂模式只有一个(对于一个项目或者一个独立模块而言)工厂类,而工厂方法模式有一组实现了相同接口的工厂类。下面我们通过修改上一节的实例来介绍工厂方法模式。

我们在不改变产品类(“足球运动员”类和“篮球运动员”类)的情况下,修改下工厂类的结构,如下图所示:






相关代码如下:


  Code: [Copy to clipboard]  
运动员.java
public interface 运动员 {       
        public void 跑();
        public void 跳();
}

足球运动员.java
public class 足球运动员 implements 运动员 {

        public void 跑(){
                //跑啊跑
        }
       
        public void 跳(){
                //跳啊跳
        }
}

篮球运动员.java
public class 篮球运动员 implements 运动员 {

        public void 跑(){
                //do nothing
        }
       
        public void 跳(){
                //do nothing
        }
}

体育协会.java
public interface 体育协会 {
        public 运动员 注册();
}

足球协会.java
public class 足球协会 implements 体育协会 {
        public 运动员 注册(){
                return new 足球运动员();
        }
}

篮球协会.java
public class 篮球协会 implements 体育协会 {
        public 运动员 注册(){
                return new 篮球运动员();
        }
}

俱乐部.java
public class 俱乐部 {
        private 运动员 守门员;
        private 运动员 后卫;
        private 运动员 前锋;

        public void test() {
                体育协会 中国足协 = new 足球协会();
               
                this.前锋 = 中国足协.注册();
                this.后卫 = 中国足协.注册();

                守门员.跑();
                后卫.跳();
        }
}



很明显可以看到,“体育协会”工厂类变成了“体育协会”接口,而实现此接口的分别是“足球协会”“篮球协会”等等具体的工厂类。

这样做有什么好处呢?很明显,这样做就完全OCP了。如果需要再加入(或扩展)产品类(比如加多个“乒乓球运动员”)的话就不再需要修改工厂类了,而只需相应的再添加一个实现了工厂接口(“体育协会”接口)的具体工厂类。



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

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

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

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

4.管理上的难度
这是个关键的问题。
我们先谈扩展。众所周知,工厂方法模式完全满足OCP,即它有非常良好的扩展性。那是否就说明了简单工厂模式就没有扩展性呢?答案是否定的。简单工厂模式同样具备良好的扩展性——扩展的时候仅需要修改少量的代码(修改工厂类的代码)就可以满足扩展性的要求了。尽管这没有完全满足OCP,但笔者认为不需要太拘泥于设计理论,要知道,sun提供的java官方工具包中也有想到多没有满足OCP的例子啊(java.util.Calendar这个抽象类就不满足OCP,具体原因大家可以分析下)。
然后我们从维护性的角度分析下。假如某个具体产品类需要进行一定的修改,很可能需要修改对应的工厂类。当同时需要修改多个产品类的时候,对工厂类的修改会变得相当麻烦(对号入座已经是个问题了)。反而简单工厂没有这些麻烦,当多个产品类需要修改是,简单工厂模式仍然仅仅需要修改唯一的工厂类(无论怎样都能改到满足要求吧?大不了把这个类重写)。

分享到:
评论

相关推荐

    C#中的简单工厂模式与工厂方法模式

    ### C#中的简单工厂模式与工厂方法模式 #### 一、引言 在软件工程领域,设计模式是一种被广泛接受的解决特定问题的最佳实践。在众多设计模式中,工厂模式因其能够灵活创建对象而备受推崇。本文将详细介绍两种常见...

    工厂模式:简单工厂模式、工厂方法模式、抽象工厂模式

    工厂模式分为三种主要类型:简单工厂模式、工厂方法模式和抽象工厂模式。 1. **简单工厂模式** 简单工厂模式是最简单的工厂模式实现,它提供一个静态方法或者类来创建对象,这个类通常被称为“工厂”。用户只需要...

    简单工厂模式-工厂方法模式-抽象工厂模式

    在软件设计模式中,工厂模式是一组非常基础且实用的设计模式,主要分为简单工厂模式、工厂方法模式和抽象工厂模式。这些模式都是为了解决对象创建的问题,通过封装对象的创建过程,使得代码更加灵活,易于扩展和维护...

    工厂方法模式和抽象工厂模式的区别

    与工厂方法模式相比,抽象工厂模式更进一步,它提供了创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。在抽象工厂模式中,不只一个产品类被创建,而是有一组相关的产品类。这种模式适用于当系统需要...

    设计模式-工厂方法模式

    工厂方法模式作为创建型模式中的一种,提供了一种创建对象的优雅方式,它不仅使对象的创建与使用分离,还极大地提高了系统的扩展性和灵活性。本文将深入探讨工厂方法模式的内部机制,以及通过反射和配置文件技术增强...

    简单工厂模式与工厂方法模式

    简单工厂模式和工厂方法模式是两种常见的设计模式,它们在软件工程中被广泛用于对象创建。这两种模式都属于创建型设计模式,它们的主要目的是抽象出对象的创建过程,使得代码更加灵活,易于扩展。 首先,我们来理解...

    抽象工厂模式+工厂方法模式+策略模式+类图实现手机加工厂

    本文将探讨三个重要的设计模式:抽象工厂模式、工厂方法模式以及策略模式,并结合一个实际的场景——手机加工厂,来具体阐述它们的应用。 首先,我们来看**抽象工厂模式**。这个模式主要用于创建相关或依赖对象的...

    工厂方法模式uml类图

    java设计模式 工厂方法模式uml类图,一张图就让你秒懂工厂方法模式

    设计模式——工厂方法模式

    工厂方法模式是面向对象设计模式中的一种,它属于创建型模式,主要解决的是当系统需要创建的对象具有多种类型,而具体创建哪种类型的对象在运行时才能确定的问题。在这个压缩包中,`FactoryMethod`可能包含了Java...

    java工厂方法模式

    同时,工厂方法模式也可以避免简单工厂模式的缺点,即当有新产品要加入到系统中时,必须对工厂类进行修改,以加入必要的处理逻辑。 工厂方法模式适合在如下场合中运用: * 当无法得知必须创建的对象属于哪个类的...

    简单工厂模式,工厂方法模式,抽象工厂模式

    本文将深入探讨三种工厂模式:简单工厂模式、工厂方法模式以及抽象工厂模式,并结合源码分析其应用场景和优缺点。 1. 简单工厂模式 简单工厂模式(Simple Factory Pattern)是一种静态工厂方法,它通过一个公共的...

    设计模式之工厂方法模式

    工厂方法模式是设计模式中的创建型模式之一,它在软件工程中扮演着非常重要的角色,尤其是在C#这样的面向对象编程语言中。工厂方法模式提供了一种封装对象创建过程的方法,使得具体的创建过程延迟到子类中进行,从而...

    肯德基:抽象工厂模式

    本章要点部分总结了抽象工厂模式的核心概念和设计原则,同时还区分了抽象工厂模式与工厂方法模式的不同,以及抽象工厂模式的具体使用场合。通过本章的学习,我们能够掌握抽象工厂模式的原理和应用,为解决实际开发中...

    简单工厂模式和工厂方法模式

    **简单工厂模式与工厂方法模式** 简单工厂模式和工厂方法模式是软件设计模式中的两种创建型模式,它们在对象创建过程中扮演着重要角色,尤其是在处理类的实例化时。这两种模式都通过提供一个专门的“工厂”类来创建...

    qt工厂模式例子qt简单工程模式源码

    3. Qt工厂模式工程 4. Qt工厂模式例程 5. Qt工厂模式例子 6. 简单工厂模式 部分源码实例: // 奔驰工厂 class BenzFactory : public AFactory { public: ICar* CreateCar() { return new BenzCar(); } }; // ...

    Java 工厂模式 抽象工厂 工厂方法模式

    本文将深入探讨Java中的工厂模式,包括基本的工厂模式、抽象工厂模式以及工厂方法模式。 **工厂模式**:工厂模式的核心思想是提供一个创建对象的接口,但让实现这个接口的类来决定实例化哪一个类。这样,客户端无需...

    工厂方法模式和抽象工厂模式

    工厂方法模式与抽象工厂模式的主要区别在于: 1. **复杂度**:工厂方法模式只关注一个产品的创建,而抽象工厂模式关注的是一个产品族的创建。 2. **灵活性**:工厂方法模式允许子类决定实例化哪个类,提供了更大的...

    深入了解工厂模式&工厂方法&抽象工厂

    2. 工厂方法模式:与简单工厂模式相比,工厂方法模式将对象的创建过程进一步抽象,由子类决定创建哪个具体类的实例。在工厂方法模式中,通常会定义一个抽象工厂类,然后为每种产品创建一个具体的工厂子类。这种方式...

    工厂方法模式的C语言实现

    工厂方法模式是一种设计模式,属于创建型模式,它提供了一种创建对象的最佳方式。在工厂方法模式中,当我们创建对象时,不会直接实例化具体的产品类,而是通过一个工厂类来创建。这样做的好处是,当需要添加新的产品...

Global site tag (gtag.js) - Google Analytics