在Java中应用设计模式 - Factory Method

【Python・统计学】(两)多因素方差分析(原理及代码) 自学笔记,分享给对统计学原理不太清楚但需要在论文中用到的小伙伴,欢迎大佬们补充或绕道。ps:本文不涉及公式讲解(文科生小白友好体质)~(部分定义等来源于知乎) 本文重点:多因素方差分析 【1.多因素方差分析简单原理】 【2.多因素方差分析步骤】 【3.多因素方差分析代码】 阅读详情
在Java中应用设计模式 - Factory Method

(来源:http://www.cn.ibm.com/developerWorks)
内容:
基本概念
简单分析
具体实施
后话:
参考资料
关于作者

刘湛 (jeru@163.net)
武汉大学信息与计算科学系学士
2001 年 9 月

在设计模式中,Factory Method也是比较简单的一个,但应用非常广泛,EJB,RMI,COM,CORBA,Swing中都可以看到此模式的影子,它是最重要的模式之一.在很多地方我们都会看到xxxFactory这样命名的类,那么,什么是Factory Method,为什么要用这个模式,如何用Java语言来实现该模式,这就是本文想要带给大家的内容.

基本概念
Factory Method是一种创建性模式,它定义了一个创建对象的接口,但是却让子类来决定具体实例化哪一个类.当一个类无法预料要创建哪种类的对象或是一个类需要由子类来指定创建的对象时我们就需要用到Factory Method 模式了.简单说来,Factory Method可以根据不同的条件产生不同的实例,当然这些不同的实例通常是属于相同的类型,具有共同的父类.Factory Method把创建这些实例的具体过程封装起来了,简化了客户端的应用,也改善了程序的扩展性,使得将来可以做最小的改动就可以加入新的待创建的类. 通常我们将Factory Method作为一种标准的创建对象的方法,当发现需要更多的灵活性的时候,就开始考虑向其它创建型模式转化

简单分析
图1是Factory Method 模式的结构图,这里提供了一些术语,让我们可以进行更方便的描述:

  1. Product: 需要创建的产品的抽象类.
  2. ConcreteProduct: Product的子类,一系列具体的产品.
  3. Creator: 抽象创建器接口,声明返回Product类型对象的Factory Method.
  4. ConcreteCreator: 具体的创建器,重写Creator中的Factory Method,返回ConcreteProduct类型的实例.

图1: Factory Method 模式结构
图1: Factory Method 模式结构

由此可以清楚的看出这样的平行对应关系: 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来体现的.

现在,请再回头看看基本概念中的那段话,开始也许觉得生涩难懂,现在是不是已经明朗化了很多.

下面让我们看看在 Java 中如何实现Factory Method模式,进一步加深对它的认识.

具体实施
先说明一点,用Factory Method模式创建对象并不一定会让我们的代码更短,实事上往往更长,我们也使用了更多的类,真正的目的在于这样可以灵活的,有弹性的创建不确定的对象.而且,代码的可重用性提高了,客户端的应用简化了,客户程序的代码会大大减少,变的更具可读性.

  1. 标准实现: 这里我采用Bruce Eckel 用来描述OO思想的经典例子 Shape.这样大家会比较熟悉一些.我完全按照图1中所定义的结构写了下面的一段演示代码.这段代码的作用是创建不同的Shape实例,每个实例完成两个操作:draw和erase.具体的创建过程委托給ShapeFactory来完成.

    1.a 首先定义一个抽象类Shape,定义两个抽象的方法.

    
    abstract class Shape {
      // 勾画shape
      public abstract void draw();
      // 擦去 shape
      public abstract void erase();
    
      public String name;
      public Shape(String aName){
      	name = aName;
      }
    }

    1.b 定义 Shape的两个子类: Circle, Square,实现Shape中定义的抽象方法

    
    // 圆形子类
    class Circle extends Shape {
      public void draw() {
        System.out.println("It will draw a circle.");
      }
      public void erase() {
        System.out.println("It will erase a circle."); 
      }
      // 构造函数
      public Circle(String aName){
      	super(aName);
      }
    }
    
    // 方形子类
    class Square extends Shape {
      public void draw() { 
        System.out.println("It will draw a square."); 
      }
      public void erase() { 
        System.out.println("It will erase a square."); 
      }
      // 构造函数
      public Square(String aName){
      	super(aName);
      }
    }
    

    1.c 定义抽象的创建器,anOperation调用factoryMethod创建一个对象,并对该对象进行一系列操作.

    
    abstract class ShapeFactory {  
      protected abstract Shape factoryMethod(String aName);
      // 在anOperation中定义Shape的一系列行为
    public void anOperation(String aName){
        Shape s = factoryMethod(aName);
      	System.out.println("The current shape is: " + s.name);
        s.draw();
    	s.erase();
      }
    }

    1.d 定义与circle和square相对应的两个具体创建器CircleFactory,SquareFactory,实现父类的methodFactory方法

    
    // 定义返回 circle 实例的 CircleFactory
    class CircleFactory extends ShapeFactory {
      // 重载factoryMethod方法,返回Circle对象
      protected Shape factoryMethod(String aName) {
        return new Circle(aName + " (created by CircleFactory)");
      }
    }
      
    // 定义返回 Square 实例的 SquareFactory
    class SquareFactory extends ShapeFactory {
      // 重载factoryMethod方法,返回Square对象
    protected Shape factoryMethod(String aName) {
        return new Square(aName + " (created by SquareFactory)");
      }
    }
    

    1.e 测试类:请注意这个客户端程序多么简洁,既没有罗嗦的条件判断语句,也无需关心ConcreteProduct和ConcreteCreator的细节(因为这里我用anOperation封装了Product里的两个方法,所以连Product的影子也没看见,当然把Product里方法的具体调用放到客户程序中也是不错的).

    
    class Main {
      public static void main(String[] args){
        ShapeFactory sf1 = new SquareFactory(); 
    	ShapeFactory sf2 = new CircleFactory();
        sf1.anOperation("Shape one");
        sf2.anOperation("Shape two");
      }
    }  
    

    运行结果如下:
    The current shape is: Shape one (created by SquareFactory)
    It will draw a square.
    It will erase a square.
    The current shape is: Shape two (created by CircleFactory)
    It will draw a circle.
    It will erase a circle.

  2. 参数化的Factory Method: 这种方式依靠指定的参数作为标志来创建对应的实例,这是很常见的一种办法.比如JFC中的BorderFactory就是个很不错的例子. 以下的这个例子是用字符串作为标记来进行判断的,如果参数的类型也不一样,那就可以用到过载函数来解决这个问题,定义一系列参数和方法体不同的同名函数,这里java.util.Calendar.getInstance()又是个极好的例子.参数化的创建方式克服了Factory Method模式一个最显著的缺陷,就是当具体产品比较多时,我们不得不也建立一系列与之对应的具体构造器. 但是在客户端我们必须指定参数来决定要创建哪一个类.

    2.a 我们在第一种方法的基础上进行修改,首先自定义一个的异常,这样当传入不正确的参数时可以得到更明显的报错信息.

    
    class NoThisShape extends Exception {
      public NoThisShape(String aName) {
        super(aName);
      }
    }
    

    2.b去掉了ShapeFactory的两个子类,改为由ShapeFactory直接负责实例的创建. ShapeFactory自己变成一个具体的创建器,直接用参数化的方法实现factoryMethod返回多种对象.

    
    abstract class ShapeFactory {  
      private static Shape s;
      private ShapeFactory() {}
        
      static Shape factoryMethod(String aName, String aType) throws NoThisShape{
        if (aType.compareTo("square")==0)
          return new Square(aName);
      	else if (aType.compareTo("circle")==0)
          return new Circle(aName);
        else throw new NoThisShape(aType);  
      }
      
      // 在anOperation中定义Shape的一系列行为
      static void anOperation(String aName, String aType) throws NoThisShape{
        s = factoryMethod(aName, aType);
        System.out.println("The current shape is: " + s.name);
        s.draw();
    	s.erase();
      }
    }
    

    2.c 测试类:这里客户端必须指定参数来决定具体创建哪个类.这个例子里的anOperation是静态函数,可以直接引用.

    
    class Main {
      public static void main(String[] args) throws NoThisShape{
        ShapeFactory.anOperation("Shape one","circle");
    	ShapeFactory.anOperation("Shape two","square");
    	ShapeFactory.anOperation("Shape three", "delta");
      }
    }
    

    运行结果如下:

    
    The current shape is: Shape one
    It will draw a circle.
    It will erase a circle.
    The current shape is: Shape two
    It will draw a square.
    It will erase a square.
    Exception in thread "main" NoThisShape: delta
            at ShapeFactory.factoryMethod(ShapeFactory.java:10)
            at ShapeFactory.anOperation(ShapeFactory.java:15)
            at Main.main(Main.java:5)
    

  3. 动态装载机制:

    有的时候我们会把ConcreteProduct的实例传给创建器作为参数,这种情况下,如果在创建器里完成创建过程,就必须判断参数的具体类型(用instanceof),然后才能产生相应的实例,那么比较好的做法是利用Java的动态装载机制来完成这件事.比如:

    我们得到一个Shape的子类s,但不知道具体是那个子类,就可以利用Class类自带的方法newInstance()得到实例

    return (Shape)s.getClass().newInstance();

    这种方法有兴趣得读者可以自己尝试,限于篇幅,不写具体代码出来了.

后话:
看完这篇文章后,相信读者对Factory Method模式有一个比较清楚的了解了.我想说的是,我们不仅应该关心一个具体的模式有什么作用,如何去实现这个模式,更应该透过现象看本质,不但知其然,还要知其所以然.要通过对模式的学习加深对面向对象思想的理解,让自己的认识得到升华.Factory Method模式看似简单,实则深刻.抽象,封装,继承,委托,多态,针对接口编程等面向对象中的概念都在这里得到了一一的体现.只有抓住了它的本质,我们才能够不拘于形式的灵活运用,而不是为了使用模式而使用模式.

参考资料

关于作者
刘湛,武汉大学信息与计算科学系学士,熟悉 Java 语言和 J2EE 思想,国内多个 Java 论坛版主,现致力于 J2EE 平台上的 eCRM 套件开发。你可以通过jeru@163.net与他联系!
huihoo.com Copyright (2001,2002,2003,2004) Allright Reseved
YOLO-FastestV2从零部署到移动端推理实战手册 本文详细介绍了YOLO-FastestV2从零开始的完整部署流程,涵盖环境搭建、模型训练、格式转换及移动端部署。通过实战步骤,指导开发者将这一轻量级目标检测模型成功部署到Android设备,实现实时推理。文章重点解析了PyTorch到NCNN的模型转换与优化,助力移动端AI应用开发。 阅读详情

相关推荐

一文介绍Linux EAS

EAS只在系统负载不重时,即系统中每个CPU的利用率都低于其算力的80%时才被启用,而且选出的最节能CPU只有比线程当前运行的CPU节约能量大于6%时,线程才会迁移到该CPU运行。因此EAS为线程选择最节约能量的CPU来运行的前提条件是很苛刻的,针对重载场景(比如游戏),EAS的功能应该很少被使用起来,针对重载场景的功耗优化,这里可能是一个值得尝试的点。算力(capacity)是CPU调度中的一个基础概念,它反映的是一个CPU的计算能力,是个规格化的值,可以通过读取Android手机的文件节点。

youzhangjing_的博客 1235

【设计模式】Factory Method(工厂方法)模式

【设计模式】Factory Method 工厂方法模式(C++实现)

Suffocatingg的博客 416

GAMES101学习-第8课进行shader的初步了解

详细理解课上展示的像素着色器GLSL,以及了解了API、OpenGL、DirectX到底是什么,还有shadertoy这个网站的初步探索。

qq_41835314的博客 1917

设计模式9-工厂模式(Factory Method)

通过对象超级模式绕开。动态内存分配(new),来避免对象创建过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定,它是结构抽象之后的第一步工作。工厂方法(Factory Method Pattern)抽象工厂(Abstract Factory Pattern)提供一个接口,用于创建相关或依赖对象的家族,而不需要指定具体的类。原型模式(Prototype Pattern)将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。

qq_41810539的博客 1348

ADF4002分频器避坑指南:常见配置错误及解决方案

本文深入解析了ADF4002分频器在实战应用中的常见陷阱与解决方案。内容涵盖寄存器配置逻辑、硬件PCB布局要点、软件驱动时序细节及系统化调试方法,重点阐述了如何避免因配置错误导致芯片无法正常工作的问题,帮助工程师高效完成高精度频率合成系统设计。

weixin_29192141的博客 96

编译opencv4.2时出现undefined reference to `jpeg_default_qtables‘错误的解决方案

操作系统:kylinV10 opencv版本:4.2.0 在编译opencv4.2.0的版本时,出现undefined reference to `jpeg_default_qtables’的错误提示,导致openc编译中断,不能继续编译,所以这个错误必须解决。 解决方案 查看错误的名字,根据名字分析,很有可能是当前系统中没有安装jpeg第三方库,到 http://www.ijg.org/上下载最新的源码包 jpegsrc.v9e.tar.gz,按如下顺序开始编译安装: tar -xzvf jpegsr.

jndingxin的专栏 5106

工厂方法模式

工厂方法模式:Factory Method 在我们的日常开发中,很多地方都可以用上工厂方法模式(事实是基础开发中,大部分人从来都不会去考虑使用)。 工厂方法模式英文定义: Define an interface for creating an object, but let subclasses decide which class to instantiate.Factory Method lets a class defer instantiation to subclasses. 工厂方法模式

threelifeadv的博客 5483

YOLO11训练中的过拟合识别与应对策略:讲解过拟合的表现、原因及应对方法(如数据增强、正则化、DropOut)

摘要 本文深入探讨了YOLO11目标检测模型中的过拟合问题。首先解析了过拟合的本质,即模型在训练数据上表现优异但泛化能力差的现象,并通过误差分解公式解释了其数学原理。文章详细列举了YOLO11中过拟合的具体表现,包括训练与验证指标分化、检测性能不一致性、置信度分布异常和类别检测不均衡等问题,并提供了对应的可视化诊断方法。 在原因分析部分,重点阐述了模型复杂度与数据规模不匹配、训练数据质量与分布问题以及训练策略不当三大根本原因。特别对比了YOLO11不同版本(n/s/m/l/x)的参数量和推荐最小数据量,指出

本博客聚焦 YOLOv11 全流程落地,涵盖架构优化、数据集处理、训练技巧与多场景部署,兼及国产数据库、Java 开发与 AI 模型应用,内容兼顾理论与工程实践,为开发者提供系统干货,助力高效提升技术能力。 243

Carson带你学设计模式:工厂方法模式(Factory Method)

手把手带你全面了解工厂方法模式

Carson带你学Android 4万+

Android14 Qcom 从Framework到Driver带你打开WIFI(二)

上篇文章讲到了UI打开WIFI以后,逐步调用到加载底层驱动以及通知等相关流程。这篇接着上文继续往下看WIFI ON的后续动作。

IAYLBL的博客 766

25、BDS-3卫星信号性能与PPP-B2b增强消息完整性分析

本文对BDS-3卫星信号性能及PPP-B2b增强消息的完整性进行了系统分析。评估了MEO、IGSO和GEO卫星的轨道与时钟精度,得出BDS-3总体SISRE为0.25 m,系统完整性可覆盖99.999%的误差。分析表明SIS中断主要由时钟调整和轨道机动引起,个别卫星存在因境外监测受限导致的非计划中断。通过自研解码软件对PPP-B2b增强消息进行采集与解析,实验结果显示BDS-3和GPS的平均历元完整性率均高于98.55%,其中卫星掩码和时钟校正消息的完整性率超过99.8%。研究还发现IGSO卫星相比MEO卫

quiet的专栏 145

factory java_在 Java 中应用设计模式 - Factory Method

在 Java 中应用设计模式 - Factory Method刘湛2001 年 9 月 06 日发布基本概念FactoryMethod是一种创建性模式,它定义了一个创建对象的接口,但是却让子类来决定具体实例化哪一个类.当一个类无法预料要创建哪种类的对象或是一个类需要由子类来指定创建的对象时我们就需要用到FactoryMethod 模式了.简单说来,FactoryMethod可以根据不同的条件产生不...

weixin_32953571的博客 214

AUTOSAR知识点 之 XCP (二):XCP基础概念

学习XCP的过程中,对XCP的基本概念要做一个全面的认知,因为里面有很多缩写以及难以理解的点,假设对此模模糊糊一知半解,那么对整个协议栈的认知会遇到极大的障碍。XCP的信号流传输图示如下XCP 标准主要分为 5 个部分:这部分提供了对于协议的一个概况介绍,包括 XCP 的功能和基础性内容。这部分内容对协议层进行了详细的规范和说明。

梦想技术家 2769

在Java中应用设计模式--Factory Method

在设计模式中,Factory Method也是比较简单的一个,但应用非常广泛,EJB,RMI,COM,CORBA,Swing中都可以看到此模式的影子,它是最重要的模式之一.在很多地方我们都会看到xxxFactory这样命名的类,那么,什么是Factory Method,为什么要用这个模式,如何用Java语言来实现该模式,这就是本文想要带给大家的内容.  基本概念  Factory Method是一

Herr Apfel的专栏 1204

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

java中factory_在Java中应用设计模式Factory Method

【IT168 技术文章】基本概念FactoryMethod是一种创建性模式,它定义了一个创建对象的接口,但是却让子类来决定具体实例化哪一个类.当一个类无法预料要创建哪种类的对象或是一个类需要由子类来指定创建的对象时我们就需要用到Factory Method 模式了.简单说来,Factory Method可以根据不同的条件产生不同的实例,当然这些不同的实例通常是属于相同的类型,具有共同的父类.Fac...

weixin_42389043的博客 155

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

在 Java 中应用设计模式 - Factory Method

原文链接:http://www-128.ibm.com/developerworks/cn/java/designpattern/factory/index.html

翔宇的blog..... 1329

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

在Java中应用设计模式 - Factory Method《转载》

在设计模式中,Factory Method也是比较简单的一个,但应用非常广泛,EJB,RMI,COM,CORBA,Swing中都可以看到此模式的影子,它是最重要的模式之一.在很多地方我们都会看到xxxFactory这样命名的类,那么,什么是Factory Method,为什么要用这个模式,如何用Java语言来实现该模式,这就是本文想要带给大家的内容.基本概念 Factory Method是一种

soleghost的专栏 935
上一篇: JSP数据库操作例程 - 存储过程 - JDBC-ODBC - SQL Server - 1.1版本
下一篇: Jive中的设计模式
lwqadmin
博客等级 码龄22年 6粉丝 92原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值