-
2019-12-26 17:55:13
在学习Spring bean的实例化方式的时候遇到的一个问题,Spring bean实例化有3种方法 1、构造器生成 2、静态工厂方法 3、实例工厂方法
那么问题来了,什么是静态工厂方法,什么是实例工厂方法?
1、静态工厂方法
就是直接可以通过静态方法来实例化一个对象public class HelloWorldFactory { public static HelloWorld getInstance(){ return new HelloWorld(); } } HelloWorldFactory.getInstance()
创建 HelloWorld 对象直接可以调用getInstance方法来进行实现
2、实例工厂方法
就是先创建类对象,然后通过对象来调用创建实例对象的方法public class HelloWorldFactory { public HelloWorld createHelloWorld(){ return new HelloWorld(); } } HelloWorldFactory helloFactory = new HelloWorldFactory(); helloFactory.createHelloWorld();
更多相关内容 -
【十六】Java反射(了解单例、用工厂模式去创建对象,它不香吗?)
2020-12-22 00:35:05目录 一、什么是类对象 二、获取类对象的方法 三、常见方法 四、工厂设计模式 五、单例设计模式 思维导图参考:【十六】Java反射思维导图 ...通过静态方法获取类对象 Class c = Claa.forName(“包名.类 -
Artiste:花式Path对象的静态工厂方法
2021-05-09 05:03:31它包含三种静态工厂方法,包括: 一种创建规则凸多边形的方法。 一种创建规则星形多边形的方法。 一种创建圆的方法。 API public static Path regularConvexPolygon(int left, int top, int right, int bottom,... -
Spring静态工厂创建对象和 实例工厂创建对象
2019-02-22 15:05:50 -
java静态工厂方法求解惑
2016-12-24 09:03:59看书上说,静态工厂方法不必在每次调用它们的时候都创建一个新对象,这个该怎么证明。 比如 public class User(){ private User(){}; public User getUser(){ return new User(); } } public class test()... -
Java 静态工厂方法详解
2019-04-08 19:09:54第一次使用静态工厂方法是在HIT《Software Construction》课程的Lab2-P1的Graph.java中,对静态工厂方法的理解也相当有限,因此撰写此博客加深对静态工厂方法的理解。 Java 静态工厂方法在实际开发中经常使用,在...Java 静态工厂方法详解
本文章主要是对《Effective Java》对静态工厂方法的理解
第一次使用静态工厂方法是在HIT《Software Construction》课程的Lab2-P1的Graph.java中,对静态工厂方法的理解也相当有限,因此撰写此博客加深对静态工厂方法的理解。
Java 静态工厂方法在实际开发中经常使用,在《Effective Java》中第二章第一条即为:考虑使用静态工厂方法代替构造器。
静态工厂方法的含义
静态工厂方法指的是在类中提供一个公有的静态方法,返回类的一个实例。
静态工厂方法的第一大优势:它们有名称
类的构造器名称被限制为类名,然而当构造器因不同的参数类型而无法确切的描述被返回的对象时,静态工厂方法却可以提供不同的函数名称作为不同构造方法。
例如如下代码:public class Person { private final SEX sex; private final String name; private final int age; private Person(String name, int age, SEX sex){ this.sex = sex; this.name = name; this.age = age; } public static Person getManInstance(String name, int age){ return new Person(name, age, SEX.man); } public static Person getWomanInstance(String name, int age){ return new Person(name, age, SEX.woman); } } enum SEX{ man, woman; }
在实际开发中,也如果是需要定义相同参数的构造器,可以通过交换参数位置的方法完成,但是这并不是一个好的方法,降低客户端代码的阅读性。
静态工厂方法的第二大优势:不必在每次调用时都创建新的对象
这种方法使得immutable的类可以使用预先构造好的实例或者是已经构造好的静态实例对象、进行重复利用。
这里提供以下immutable类的五条规则:
- 不提供任何mutator
- 保证类不会被扩展
- 所有的域都是final的
- 所有的域都是私有的
- 确保对于任何可变组件的互斥性访问
示例代码如下:
public class Position{ private final int x; private final int y; private static Position ORIGIN = new Position(0,0); private Position(int x, int y){ this.x = x; this.y = y; } public static Position getORIGIN(){ return ORIGIN; } public int getX(){ return x; } public int getY(){ return y; } }
静态工厂方法第三大优势:他们可以返回原返回类型的任何子类型的对象
这样我们在选择返回对象的类时就有了更大的灵活性。
这种灵活性的一种应用是,API可以返回对象,同时又不会使对象的类变成公有的。以这种方式隐藏实现类会使API变得非常简洁。这项技术适用于基于接口的框架(interface-basedframework),因为在这种框架中,接口为静态工厂方法提供了自然返回类型。接口不能有静态方法,因此按照惯例,接口Type的静态工厂方法被放在一个名为Types的不可实例化的类(见第4条)中。
示例代码如下:public class Person { public static Person getStudent(){ return new Student(); } } class Student extends Person { }//仅为一无内涵的示例
静态工厂方法的第四大优势在于,在创建参数化类型的实例的时候,他们使代码变得更加简介
此优势主要体现在泛型初始化时,示例代码如下:
// 不使用静态工厂方法的情况: Map<String, Integer> map = new HashMap<String, Integer>(); // HashMap中如果存在此方法: public Map<K,V> getInstance(){ return new HashMap<K,V>(); } // 即可简化成以下代码 Map<String, Integer> map = HashMap.getInstance();
静态方法的主要缺点是,类如果不含有共有的或受保护的构造器,就不能被子类化。
这一部分较有体会,例如以下代码(错误示例)
public class Person { private final SEX sex; private final String name; private final int age; private Person(String name, int age, SEX sex){ this.sex = sex; this.name = name; this.age = age; } public static Person getManInstance(String name, int age){ return new Person(name, age, SEX.man); } public static Person getWomanInstance(String name, int age){ return new Person(name, age, SEX.woman); } } class Student extends Person { }
实际在编译器的静态检查中会报错,原因是父类缺少公有的构造方法,而子类无法调用父类的私有构造器,导致子类无法生成构造器。
静态工厂方法的第二个缺点在于,他们与其他的静态方法实际没有任何区别
下面是一些静态工厂方法的惯用名称:
- valueOf——不太严格地讲,该方法返回的实例与它的参数具有相同的值。这样的静态工厂方法实际上是类型转换方法。
- of—— valueOf的一 种更为简洁的替代,在EnumSet (见第32条)中使用并流行起来。
- getInstance-返回的实例是通过方法的参数来描述的,但是不能够说与参数具有同样的值。 对于Singleton来说, 该方法没有参数,并返回唯一的实例。
- newInstance——像 getInstance-样, 但newInstance 能够确保返回的每个实例都与所有其他实例不同。
- getType——像getInstance- 样, 但是在工厂方法处于不同的类中的时候使用。Type表示工厂方法所返回的对象类型。
- newType——像newinstance一样,但是在工厂方法处于不同的类中的时候使用。Type表示工厂方法所返回的对象类型。
要不,点个赞?~
-
深入理解设计模式-简单工厂模式(静态工厂方法模式)
2022-02-18 16:10:05简单工厂模式是属于创建型模式,在简单工厂模式中用于被创建实例的方法通常为静态(static)方法,因此又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象...
一、定义
简单工厂模式是属于创建型模式,在简单工厂模式中用于被创建实例的方法通常为静态(static)方法,因此又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
二、使用场景
- 工厂类负责创建的对象比较少;
- 客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;
- 由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。
三、代码样例
1.需求
用面向对象语言实现一个计算器控制台程序,要求输入两个数和运算符号,得到结果。
2.类图
3.运算操作类
/** * 操作类抽象类 * */ public abstract class Operation { public double numberA; public double numberB; public abstract double result(); }
/** * 加法类 * */ public class OperationAdd extends Operation { @Override public double result() { return numberA + numberB; } }
/** * 除法类 * */ public class OperationDiv extends Operation { @Override public double result() { if (numberB == 0) { throw new RuntimeException("divided by 0"); } return numberA / numberB; } }
/** * 乘法类 * */ public class OperationMul extends Operation { @Override public double result() { return numberA * numberB; } }
/** * 减法类 * */ public class OperationSub extends Operation { @Override public double result() { return numberA - numberB; } }
4.操作工厂类
/** * 操作类工厂类 * */ public class OperationFactory { public static Operation createOperation(char operator) { Operation operation = null; switch (operator) { case '+': operation = new OperationAdd(); break; case '-': operation = new OperationSub(); break; case '*': operation = new OperationMul(); break; case '/': operation = new OperationDiv(); break; default: throw new RuntimeException("unsupported operation"); } return operation; } }
5.客户端类
/** * 使用工厂方法生成实例完成运算操作 * */ public class Calculator { public static void main(String[] args) { Operation operation; char operator; operator = '+'; operation = OperationFactory.createOperation(operator); operation.numberA = 1.2; operation.numberB = 2.3; System.out.println(operation.result()); } }
四、优缺点
优点:
- 工厂类包含必要的逻辑判断,可以决定在什么时候创建哪一个产品的实例。客户端可以免除直接创建产品对象的职责
- 客户端无需知道所创建具体产品的类名,只需知道参数即可
- 也可以引入配置文件,在不修改客户端代码的情况下更换和添加新的具体产品类。(这也是我在开始的披萨店里遇到没有的披萨的解决情况)
缺点:
- 工厂类集中了所有产品的创建逻辑,职责过重,一旦异常,整个系统将受影响
- 使用简单工厂模式会增加系统中类的个数(引入新的工厂类),增加系统的复杂度和理解难度
- 系统扩展困难,一旦增加新产品不得不修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂
- 简单工厂模式使用了static工厂方法,造成工厂角色无法形成基于继承的等级结构。
这些缺点在工厂方法模式中得到了一定的克服。
结尾
- 感谢大家的耐心阅读,如有建议请私信或评论留言。
- 如有收获,劳烦支持,关注、点赞、评论、收藏均可,博主会经常更新,与大家共同进步
-
Spring创建对象的三种方法之二静态工厂创建(源码)
2016-09-25 13:54:18不说废话,直接源码,详细关于理论方法的知识,自己去网上面找吧,这个是关于Spring创建对象的三种方法中的:用静态工厂创建。 需要用到三个类, 第一个类: package dao; public class AA { public ... -
Spring通过工厂创建对象的三种方法详解(工厂设计模式)
2020-06-25 19:34:02在创建对象的过程中,常常创建出的对象并不能直接使用,它可能需要若干步复杂的步骤,处理完成后才能正常使用。比如有一个网络连接的类NetConn,类中有加载配置文件的方法load(),测试网络连通性的方法ping(),连接网络... -
手把手教你应用三种工厂模式在SpringIOC中创建对象实例【案例详解】
2021-07-12 00:16:58二、通过静态工厂方法创建Bean实例 三、通过实例工厂方法创建Bean实例 四、通过自定义的factoryBean来创建bean对象 Hello,你好呀,我是灰小猿!一个超会写bug的程序猿! 工厂模式相信很多小伙伴们都有听说过,... -
Spring通过工厂方法创建对象
2018-10-01 21:17:37静态工厂 工厂类 public class AppleFactory { public static Apple newInstance(String color) { return new Apple(color); } } xml &lt;bean id="AppleFactory" class=... -
Spring开发之静态工厂创建对象+动态工厂创建对象+构造方法创建对象+set方法注入+构造方法注入
2016-12-07 18:06:48第二步:创建类 第三步:创建Spring开发之applicationContext.xml文件 第四步:编写代码和测试 第一步:导入Spring开发之必须用到的jar包 第二步:创建类 User类 package com.domain; ... -
Java 设计模式之静态工厂方法模式
2019-09-16 17:12:12静态工厂方法模式,又称为简单工厂模式,是最简单最易理解的工厂模式,本文通过一个 “月饼” 例子,一起来学习下这种设计模式吧! -
ej3-1优先使用静态工厂方法而非构造函数来创建对象
2020-01-09 14:31:15条款1 优先使用静态工厂方法而非构造函数来创建对象 允许客户端创建一个实例的传统方法是:提供一个公共构造函数;有另外一个必须成为每个程序员的编程技巧:优先使用类提供的只简单返回实例的公共静态工厂方法来... -
用静态工厂方法代替构造器
2019-12-18 20:40:17参考于《Effective Java》 前言 对于类而言,获得其实例最常见的方式就是提供一个构造器。 如果我们不写构造器,编译器会...通过私有化构造器,无法直接new对象,而是通过运行静态工厂方法获取对象实例。 这么做既... -
为什么要在JAVA工厂模式中使用静态方法
2020-12-22 20:12:21如果不使用工厂模式,你需要直接使用构造方法来创建对象: Foo x = new Foo() 使用工厂模式,可以取而代之的调用工厂方法: Foo x = Foo.create() 工厂类的构造方法被标记为private,所以构造方法除了 -
简单工厂模式(静态工厂方法模式)
2019-05-17 16:23:07简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单... -
java的静态工厂方法
2019-11-19 20:41:031.什么是静态工厂方法 类可以提供一个共有的静态工厂方法(static factory method),它只是一个放回类的实例的静态方法。 下面是一个来自Boolean(基本类型boolean的装箱类)的简单实例。 /** 将boolean基本类型转换... -
Java 使用静态工厂方法替代构造方法
2020-04-13 09:35:061. 考虑使用静态工厂方法替代构造方法 一个类允许客户端获取其实例的传统方式是提供一个公共构造方法。 其实还有另一种技术应该成为每个程序员工具箱的一部分。 一个类可以提供一个公共静态工厂方法,它只是一个返回... -
静态工厂方法和实例工厂方法
2017-02-05 11:56:26在学习Spring bean的实例化方式的时候遇到的一个问题,Spring bean实例化有3种方法 1、构造器生成 2、静态工厂方法 3、实例工厂方法 那么问题来了,什么是静态工厂方法,什么是实例工厂方法? 静态工厂方法: ... -
Java静态工厂方法与工厂模式
2019-02-25 14:02:56静态工厂方法和工厂模式很像,但是在java中还是有很大区别的。 (一)静态工厂方法vs工厂模式 对于一个类来说,为了让客户端获得一个自身的实例,最常用的方法就是提供一个公有的构造器。除了这种使用构造器的方法... -
Java中23种设计模式之静态工厂方法
2019-02-18 22:55:37初步接触设计模式,初步了解静态工厂方法,了解还不全面,我们先一步步了解一下。 一、背景介绍 工厂模式是设计模式的一种,设计模式是自程序开发逐渐就有的,提高开发效率的一种设计思路,先前的开发者们一直在... -
静态工厂方法和实例工厂方法的区别
2018-03-01 20:52:21在学习Spring bean的实例化方式的时候遇到的一个问题,Spring bean实例化有3种方法 1、构造器生成 2、静态工厂方法 3、实例工厂方法 那么问题来了,什么是静态工厂方法,什么是实例工厂方法? 静态工厂方法 ... -
spring--静态工厂方法和实例工厂方法注入
2018-09-17 22:44:53一、静态工厂方法注入bean 利用静态工厂方法可以把bean注入到IOC容器中。在XML文件中配置bean时,要指定class的属性为工厂的类;factory-method属性指定工厂类中工厂方法,用于创建bean;constrctor-arg用于给工厂... -
静态工厂方法构造对象优缺点
2009-12-03 12:40:00对于一个类,要获取它的一个实例,通常的做法是提供一个...其实,静态工厂方法获取对象实例,我们并不陌生,我们来看看API中的一个实例:java.lang.Boolean类:public static Boolean valueOf(boolean b){ return -
设计模式之静态工厂、工厂方法和抽象工厂的联系与区别
2017-02-06 11:31:20解析: 开闭原则:对扩展开放,对修改封闭。静态工厂增加需要是修改源代码,对修改不封闭,不符合开闭原则。 -
为什么说静态工厂方法可能会比构造器更好?听说读完就会有一个女朋友?
2020-01-03 21:00:52这种方式直接创建对象,相当于对JVM说,我要一个对象,然后JVM会去根据 双亲委派原则 去 加载 、 验证 、 准备 、 解析 ( new一个对象发生了什么? ),所以开支是蛮大的,尤其在重复新建一个对象的时候。小斌哥我... -
静态工厂方法和实例工厂方法注入bean
2017-11-26 17:41:24一、静态工厂方法注入bean利用静态工厂方法可以把bean注入到IOC容器中。在XML文件中配置bean时,要指定class的属性为工厂的类;factory-method属性指定工厂类中工厂方法,用于创建bean;constrctor-arg用于给工厂... -
Java 设计模式之静态工厂、工厂方法、抽象工厂和 Builder 模式的区别
2019-09-27 16:29:29前面几篇文章,我们学习了几种工厂模式和 Builder 模式,都可以用来得到产品对象,那他们有什么区别呢?我们该怎么选择呢? -
Java中用静态工厂方法代替构造器的优缺点
2016-09-04 00:31:45Effective Java学习几笔,静态工厂方法的善用。 一般情况下,对于类而言,我们获取一个类的实例时,最常用的方法是提供一个公有的构造器。 但是还有一种方法,类可以提供一个公有的静态工厂方法,它只是个返回类的...