在设计模式中,Factory Method模式是一种比较简单的设计模式,应用比较广泛,但也是一种比较重要的设计模式之一。在很多地方我们都会看到xxxFactory这样命名的类,那么,什么是Factory Method,为什么要用这个模式,如何用Java语言来实现该模式?
【1】基本概念
FactoryMethod是一种创建性模式,它定义了一个创建对象的接口,但是却让子类来决定具体实例化哪一个类.当一个类无法预料要创建哪种类的对象或是一个类需要由子类来指定创建的对象时我们就需要用到Factory Method
模式了.简单说来,Factory Method可以根据不同的条件产生不同的实例,当然这些不同的实例通常是属于相同的类型,具有共同的父类.Factory Method把创建这些实例的具体过程封装起来了,简化了客户端的应用,也改善了程序的扩展性,使得将来可以做最小的改动就可以加入新的待创建的类. 通常我们将Factory Method作为一种标准的创建对象的方法,当发现需要更多的灵活性的时候,就开始考虑向其它创建型模式转化。
【2】简单分析
我们先来看一下该设计模式的UML图:
上图是Factory Method 模式的结构图,让我们可以进行更方便的描述:
-
Product: 需要创建的产品的抽象类.
-
ConcreteProduct: Product的子类,一系列具体的产品.
-
Creator: 抽象创建器接口,声明返回Product类型对象的Factory Method.
-
ConcreteCreator: 具体的创建器,重写Creator中的Factory Method,返回ConcreteProduct类型的实例.
同时可以清楚的看出这样的平行对应关系: Product <====> Creator ; ConreteProduct <====> ConreteCreator
抽象产品对应抽象创建器,具体产品对应具体创建器.这样做的好处是什么呢?为什么我们不直接用具体的产品和具体的创建器完成需求呢?实际上我们也可以这样做.但通过Factory Method模式来完成,客户(client)只需引用抽象的Product和Creater,对具体的ConcreteProduct和ConcreteCreator可以毫不关心,这样做我们可以获得额外的好处:
-
首先客户端可以统一从抽象创建器获取产生的实例,Creator的作用将client和产品创建过程分离开来,客户不用操心返回的是那一个具体的产品,也不用关心这些产品是如何创建的.同时,ConcreteProduct也被隐藏在Product后面,ConreteProduct继承了Product的所有属性,并实现了Product中定义的抽象方法,按照Java中的对象造型(cast)原则,通过ConcreteCreator产生的ConcreteProduct可以自动的上溯造型成Product.这样一来,实质内容不同的ConcreteProduct就可以在形式上统一为Product,通过Creator提供给client来访问.
-
其次,当我们添加一个新的ConcreteCreator时,由于Creator所提供的接口不变,客户端程序不会有丝毫的改动,不会带来动一发而牵全身的灾难, 这就是良好封装性的体现.但如果直接用ConcreteProduct和ConcreteCreator两个类是无论如何也做不到这点的. 优良的面向对象设计鼓励使用封装(encapsulation)和委托(delegation),而Factory Method模式就是使用了封装和委托的典型例子,这里封装是通过抽象创建器Creator来体现的,而委托则是通过抽象创建器把创建对象的责任完全交给具体创建器ConcreteCreator来体现的.
【3】如何用java语言来实现该模式
该模式采用一个Shape(形状)的经典例子作为一个实例来展示如何实现Factory Method模式,先看下代码的结构图:
3.1首先定义一个抽象类Shape,定义两个抽象的方法.
- packagecom.andyidea.patterns.product;
- /**
- *Product:需要创建的产品的抽象类.
- *@authorAndy.Chen
- *
- */
- publicabstractclassShape{
- publicStringname;
- publicShape(StringaName){
-
this.name=aName;
- }
- //绘画
- publicabstractvoiddraw();
- //擦除
- publicabstractvoiderase();
- }
3.2 定义 Shape的两个子类: Circle, Square,实现Shape中定义的抽象方法
Circle中的源码如下:
- packagecom.andyidea.patterns.concreteproduct;
- importcom.andyidea.patterns.product.Shape;
- /**
- *圆形子类(ConcreteProduct:Product的子类,一系列具体的产品.)
- *@authorAndy.Chen
- *
- */
- publicclassCircleextendsShape{
- publicCircle(Stringname){
- super(name);
- }
- @Override
- publicvoiddraw(){
- System.out.println("ItwilldrawaCircle");
- }
- @Override
- publicvoiderase(){
- System.out.println("ItwilleraseaCircle");
- }
- }
Square中的源码:
- packagecom.andyidea.patterns.concreteproduct;
- importcom.andyidea.patterns.product.Shape;
- /**
- *方形子类(ConcreteProduct:Product的子类,一系列具体的产品.)
- *@authorAndy.Chen
- *
- */
- publicclassSquareextendsShape{
- publicSquare(Stringname){
- super(name);
- }
- @Override
- publicvoiddraw(){
- System.out.println("ItwilldrawaSquare");
- }
- @Override
- publicvoiderase(){
- System.out.println("ItwilleraseaSquare");
- }
- }
3.3 定义抽象的创建器,anOperation调用factoryMethod创建一个对象,并对该对象进行一系列操作.
- packagecom.andyidea.patterns.creator;
- importcom.andyidea.patterns.product.Shape;
- /**
- *Creator:抽象创建器接口,声明返回Product类型对象的FactoryMethod.
- *@authorAndy.Chen
- *
- */
- publicabstractclassShapeFactory{
- protectedabstractShapefactoryMethod(StringaName);
- publicvoidanOperation(StringaName){
-
Shapes=factoryMethod(aName);
- System.out.println("Thecurrentshapeis:"+s.name);
- s.draw();
- s.erase();
- }
- }
3.4 定义与circle和square相对应的两个具体创建器CircleFactory,SquareFactory,实现父类的methodFactory方法
CircleFactory中的源码:
- packagecom.andyidea.patterns.concretecreator;
- importcom.andyidea.patterns.concreteproduct.Circle;
- importcom.andyidea.patterns.creator.ShapeFactory;
- importcom.andyidea.patterns.product.Shape;
- /**
- *ConcreteCreator:具体的创建器,重写Creator中的FactoryMethod,
- *返回ConcreteProduct类型的实例.
- *@authorAndy.Chen
- *
- */
- publicclassCircleFactoryextendsShapeFactory{
- @Override
- protectedShapefactoryMethod(StringaName){
- returnnewCircle(aName+"(createdbyCircleFactory)");
- }
- }
SquareFactory中的源码:
- packagecom.andyidea.patterns.concretecreator;
- importcom.andyidea.patterns.concreteproduct.Square;
- importcom.andyidea.patterns.creator.ShapeFactory;
- importcom.andyidea.patterns.product.Shape;
- /**
- *ConcreteCreator:具体的创建器,重写Creator中的FactoryMethod,
- *返回ConcreteProduct类型的实例.
- *@authorAndy.Chen
- *
- */
- publicclassSquareFactoryextendsShapeFactory{
- @Override
- protectedShapefactoryMethod(StringaName){
- returnnewSquare(aName+"(createdbySquareFactory)");
- }
- }
3.5 测试类MainClient:这个客户端程序没有罗嗦的条件判断语句,也无需关心ConcreteProduct和ConcreteCreator的细节(因为这里我用anOperation封装了Product里的两个方法,所以连Product的影子也没看见,当然把Product里方法的具体调用放到客户程序中也是不错的).
- packagecom.andyidea.patterns.client;
- importcom.andyidea.patterns.concretecreator.CircleFactory;
- importcom.andyidea.patterns.concretecreator.SquareFactory;
- importcom.andyidea.patterns.creator.ShapeFactory;
- /**
- *测试设计模式类
- *@authorAndy.Chen
- *
- */
- publicclassMainClient{
- publicstaticvoidmain(String[]args){
-
ShapeFactorysf1=newCircleFactory();
-
ShapeFactorysf2=newSquareFactory();
- System.out.println("WelcometoAndy.ChenBlog!"+"\n"
- +"FactoryMethodPatterns."+"\n"
- +"-------------------------------");
- sf1.anOperation("Shape-Circle");
- sf2.anOperation("Shape-Square");
- }
- }
【4】程序运行结果如下:
- WelcometoAndy.ChenBlog!
- FactoryMethodPatterns.
- -------------------------------
- Thecurrentshapeis:Shape-Circle(createdbyCircleFactory)
- ItwilldrawaCircle
- ItwilleraseaCircle
- Thecurrentshapeis:Shape-Square(createdbySquareFactory)
- ItwilldrawaSquare
- ItwilleraseaSquare
【5】总结:用Factory Method模式创建对象并不一定会让我们的代码更短,实事上往往更长,我们也使用了更多的类,真正的目的在于这样可以灵活的,有弹性的创建不确定的对象.而且,代码的可重用性提高了,客户端的应用简化了,客户程序的代码会大大减少,变的更具可读性。
分享到:
相关推荐
《设计模式之——工厂方法(Factory Method)》 在软件工程中,设计模式是一种解决常见问题的可重用解决方案,它被广泛应用于构建高质量、可维护的代码。工厂方法是面向对象设计模式的一种,属于创建型模式。这个...
工厂方法模式是面向对象设计模式中的行为型模式之一,它提供了一种创建对象的最佳方式。在工厂方法模式中,一个工厂类负责创建对象,而具体的创建过程被延迟到了子类中,使得子类可以在不修改原有代码的基础上决定...
C++的设计模式之工厂方法模式(Factory Method) C++的设计模式之工厂方法模式(Factory Method) C++的设计模式之工厂方法模式(Factory Method) C++的设计模式之工厂方法模式(Factory Method)
今天我们要探讨的是设计模式中的一个经典成员——工厂方法模式(Factory Method Pattern)。工厂方法模式是创建型设计模式的一种,它提供了一种创建对象的最佳方式。 ### 一、什么是工厂方法模式? 工厂方法模式...
- 工厂方法模式(Factory Method):定义一个用于创建对象的接口,让子类决定实例化哪一个类。 - 抽象工厂模式(Abstract Factory):提供一个接口,用于创建相关或依赖对象的家族,而无需指定它们的具体类。 - ...
Factory Method(工厂方法)模式是GoF(Gang of Four)设计模式之一,属于创建型模式。此模式的核心在于提供了一种创建对象的方式,而不必将具体的类名硬编码到程序中,从而增强了程序的灵活性和可维护性。 #### ...
工厂方法模式是一种创建型设计模式,它提供了一个创建对象的接口,但允许子类决定实例化哪一个类。这样,工厂方法将类的实例化推迟到子类。在Java中,我们可以定义一个工厂接口,然后由具体的子类实现这个接口,创建...
设计模式C++学习之工厂方法模式(Factory Method)
C#面向对象设计模式纵横谈(5):Factory Method 工厂方法模式(创建型模式) (Level 300)
2. **工厂方法模式**(Factory Method Pattern):定义一个创建对象的接口,让子类决定实例化哪一个类。工厂方法让类的实例化推迟到子类。 3. **抽象工厂模式**(Abstract Factory Pattern):提供一个创建一系列...
在众多设计模式中,“工厂方法模式”(Factory Method Pattern)尤为突出,它是一种创建型设计模式,用于解决在类的实例化过程中,如何避免硬编码的问题,同时保持系统的灵活性与可扩展性。 #### 工厂方法模式的...
本篇文章将详细探讨"设计模式之Factory",它是一种非常基础且重要的创建型设计模式。 Factory模式的核心思想是提供一个接口或者抽象类,用于创建某一类对象,但允许其子类决定实例化哪一个类。这种模式使得创建过程...
工厂方法模式是面向对象设计模式中的一个核心模式,属于创建型模式。它的主要目的是通过引入一个工厂接口,将具体的对象创建过程封装起来,使得客户端在使用时无须关心产品类的确切实现,只需要通过工厂来获取所需的...
在压缩包中的`FactoryMethod`文件很可能包含了示例代码,这些代码演示了如何在实际的Qt项目中运用工厂方法模式,例如定义工厂类、产品类以及它们之间的关系,以及如何在主程序中调用这些工厂来创建和使用对象。...
工厂方法(Factory Method)是面向对象设计模式中的一个基础且广泛应用的模式,它属于创建型模式,主要目的是为了解耦对象的创建过程。本文将深入探讨工厂方法的设计理念、实现方式及其在实际开发中的应用。 ### ...
“设计模式之工厂方法模式”表明我们将讨论的是设计模式中的工厂方法,它是创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。通过工厂方法,我们可以避免在客户端代码中直接实例化具体产品,而是通过...
工厂方法(Factory Method)是工厂模式的一种具体实现,它是《Head First 设计模式》这本书中讲解的重点之一。在这个模式中,一个工厂类声明了一个创建对象的抽象方法,但并不实现这个方法。而是由子类决定要实例化...