工厂设计模式(java版本、spring源码中使用的工厂模式)

工厂设计模式(java版本、spring源码中使用的工厂模式)

最近在学习spring源码,发现在IoC容器初始化的时候创建各种bean,然后在代码中看到各种beanFactory和factoryBean,很显然spring容器在创建bean的过程是使用了工厂设计模式,那么正好总结一下工厂设计模式。

工厂模式分为简单工厂、工厂方法、抽象工厂三种

一、简单工厂

简单工厂的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类

spring中创建bean的过程中无论是通过xml配置还是通过配置类进行创建bean,大部分都是通过简单工厂来进行创建的。比如说当容器拿到了bean的beanname和class类型后,动态的通过反射创建具体的某个对象,最后将创建的对象放到Map中。那么为什么要使用简单工厂、简单工厂有什么优点、以及如何使用简单工厂呢?我们学习设计模式肯定要知道为什么要使用他,在什么场景使用它,我们创建对象的时候为什么不使用new对象呢,为什么要使用工厂模式和构造者模式呢,这肯定是有原因的

场景:现在我们来生产车。分别能生产宝马、奔驰、大众,正常情况下我们要使用创建这三种车的时候,直接new一个对象就行,然后调用其他的方法。代码如下所示

Car.java

package factory;

public interface Car {

	void run();
}

BMWCar .java

package factory;

public class BMWCar implements Car{

	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("bmw car running...");
	}

}

 BenChiCar .java

 

package factory;

public class BenChiCar implements Car{

	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("benchi car running");
	}

}

 DaZhongCar .java

package factory;

public class DaZhongCar implements Car{

	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("dazhong car running...");
	}

}

 SimpleFactoryTest .java

package factory;

public class SimpleFactoryTest {

	public static void main(String[] args) {
		Car bmw = new BMWCar();
		Car benchi = new BenChiCar();
		Car dazhong = new DaZhongCar();
		bmw.run();
		benchi.run();
		dazhong.run();
	}
}

 上述代码非常简单,并且也没问题,完全可以使用,那么现在问题来了

1,现在随着扩展,有这样的一个要求,就是生产汽车的过程中,还需要做一些其他的操作,比如给轮胎打气、检测发动机、检测安全气囊…等等非常多且比较复杂的工作,虽然有些工作,我们可以放在构造方法中去完成,但是有些操作不适合放在构造方法中去执行的,那么怎么办?每次创建对象的时候都需要操作这些方法?只在一个地方构造对象还好,如果是在n多个地方都创建该对象呢?必然会导致代码的重复。

2、现在业务发生了更改,我们现在不生产奔驰,而是生产奔奔,那么需要将以前生产奔驰的地方全部改成生产奔奔,怎么修改?所有new BenchiCar()的地方全部改成new BenbenCar()?

好了那么这个时候可以使用我们的简单工厂方法

创建工厂类解决上述两个问题

CarFactory .java

package factory;

public class CarFactory {

	public Car getCar(String carName) {
		Car car = null;
		if(carName.equals("bmw")) {
			car = new BMWCar();
			/*
			 *这里可以统一执行一些操作 ,比如给轮胎打气,给电瓶充电、检测安全气囊等等
			 */
		}else if(carName.equals("benchi")) {
			//car = new BenChiCar();
			//比如现在要将以前所有的奔驰车全部改成奔奔车,只需要将上述的car = new BenChiCar();改成如下
			car = new BenBenCar();
			/*
			 *这里可以统一执行一些操作 ,比如给轮胎打气,给电瓶充电、检测安全气囊等等
			 */
		}else if(carName.equals("dazhong")) {
			car = new DaZhongCar();
			/*
			 *这里可以统一执行一些操作 ,比如给轮胎打气,给电瓶充电、检测安全气囊等等
			 */
		}
		return car;
	}
}

SimpleFactoryTest .java

package factory;

public class SimpleFactoryTest {

	public static void main(String[] args) {
		CarFactory carFactory = new CarFactory();
		Car bmw = carFactory.getCar("bmw");
		Car benchi = carFactory.getCar("benchi");
		Car dazhong = carFactory.getCar("dazhong");
		bmw.run();
		benchi.run();
		dazhong.run();
	}
}

是不是觉得很ok呢?不用牵一发而动全身,其实spring中beanfactory创建bean就是通过上述的简单工厂进行创建,只是他底层通过反射的方式创建对象。简单工厂就是让创建者屏蔽创建的过程,只管使用就行。是不是所有创建对象的方式都能通过上面的方式去创建呢,假如现在有随着业务的扩展,我需要创建的车越来越多了,新增了丰田、荣威、比亚迪,那怎么办?难道要每一次都需要去修改这个工厂方法中的getCar()方法吗?这显然不符合设计模式中的开闭原则(对修改关闭、对扩展开放),那怎么办?下面工厂方法解决了这个问题

二、工厂方法

根据上面的问题描述,直接上代码吧

上面的汽车的接口Car和具体的类我就不重复贴代码了

CarFactory .java

package factorymethod;

public interface CarFactory {

	Car getCar();
}

BMWCarFactory .java

package factorymethod;


public class BMWCarFactory implements CarFactory{

	@Override
	public Car getCar() {
		// TODO Auto-generated method stub
		return new BMWCar();
	}

	
}

FengtianCarFactory .java

package factorymethod;

public class FengtianCarFactory implements CarFactory{

	@Override
	public Car getCar() {
		// TODO Auto-generated method stub
		return new FengTianCar();
	}

}

 FactoryMethodTest .java

package factorymethod;

public class FactoryMethodTest {

	public static void main(String[] args) {
		CarFactory benbenFactory = new BenBenCarFactory();
		Car benben = benbenFactory.getCar();
		benben.run();
		CarFactory fengtianFactory = new FengtianCarFactory();
		Car fengtian = fengtianFactory.getCar();
		fengtian.run();
	}
}

这个时候如果我们需要新增汽车品牌的时候,只需要新建相应的工厂,然后将创建对象的过程延迟到子类(实现类)具体实现接口只负责定义规则,这种设计就是符合开闭原则,对修改关闭,对扩展开放,spring中FactoryBean就是这种设计模式,当FactoryBean的getObject就是通过他的实现类具体的去生产某个bean,所以FactoryBean.getObject并不是返回一个Factorybean的对象,而是返回由Factorybean创建的相应的bean,就好比我们上面FenttianFactory.getcar返回的不是工厂,而是返回对应的fengtian car

抽象工厂留着下次再讲吧,如有问题,欢迎指正,大家一起讨论

 

 

 

 

 

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/111238.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 设计模式之享元(flyweight)模式

    现在在大力推行节约型社会,“浪费可耻,节俭光荣”。在软件系统中,有时候也会存在资源浪费的情况,例如,在计算机内存中存储了多个完全相同或者非常相似的对象,如果这些对象的数量太多将导致系统运行代价过高。那

    2021年12月28日
  • Java设计模式——策略模式[通俗易懂]

    Java设计模式——策略模式[通俗易懂]策略模式1.策略模式简介策略模式:策略模式是一种行为型模式,它将对象和行为分开,将行为定义为一个行为接口和具体行为的实现。策略模式最大的特点是行为的变化,行为之间可以相互替换。每个if判断都可以理解为就是一个策略。本模式使得算法可独立于使用它的用户而变化2.模式结构策略模式包含如下角色:Strategy:抽象策略类:策略是一个接口,该接口定义若干个算法标识,即定义了若干个抽象方法(如下图的algorithm())Context:环境类/上下文类:上下文是依赖于接口的类(

  • 一、设计模式-开篇—为什么我要去旅行? #和设计模式一起旅行#

    独学而无友,则孤陋而寡闻。——《礼记·学记》写在开篇,本篇是一个综合帖,里面可能会记录一些我的学习感受,也可能记录一些我学习的资料的说明,总之这就是一个大杂烩的博文。开篇杂谈最近学习一些技术之外的其他东西,怎么进行时间管理了,怎么坚持去做一件事情了,还是学到了一些其他的新的东西!做一件事情最难的是什么,是启动!启动之后最难是什么,是坚持!很多时候大的道理我们都懂,但…

  • 前端开发中常用的几种设计模式有哪些_设计模式原理

    前端开发中常用的几种设计模式有哪些_设计模式原理设计模式是对软件设计开发过程中反复出现的某类问题的通用解决方案。设计模式更多的是指导思想和方法论,而不是现成的代码,当然每种设计模式都有每种语言中的具体实现方式。学习设计模式更多的是理解各种模式的内在思想和解决的问题,毕竟这是前人无数经验总结成的最佳实践,而代码实现则是对加深理解的辅助。设计模式可以分为三大类:结构型模式(StructuralPatterns):通过识别系统中组件间的简单关系来简化系统的设计。 创建型模式(CreationalPatterns):处理对象的创..

    2022年10月25日
  • JAVA设计模式之门面模式(外观模式)[通俗易懂]

    医院的例子  现代的软件系统都是比较复杂的,设计师处理复杂系统的一个常见方法便是将其“分而治之”,把一个系统划分为几个较小的子系统。如果把医院作为一个子系统,按照部门职能,这个系统可以划分为挂号、门诊、划价、化验、收费、取药等。看病的病人要与这些部门打交道,就如同一个子系统的客户端与一个子系统的各个类打交道一样,不是一件容易的事情。  首先病人必须先挂号,然后门诊。如果医生要求化验,病人必

  • 23种设计模式汇总整理

    设计模式分为三大类:创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式结构型模式,共七种:适配器模式、装饰者模式、代理模式、外观模式、桥接模式、组合模式、享元模式。行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。其实还有两类:并发型模式和线程池模式。…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号