设计模式之工厂模式
在面向对象编程中,术语“工厂”表示一个负责创建其他类型对象的类。通常情况下,作为一个工厂的类有一个对象以及与它关联的多个方法。客户端使用某些参数调用此方法之后,工厂会据此创建所需类型的对象,然后将它们返回给客户端。
工厂具有下列优点:松耦合,即对象的创建可以独立于类的实现;客户端无需了解创建对象的类,但是照样可以使用它来创建对象。它只需要知道需要传递的接口、方法和参数,就能够创建 所需类型的对象了。这简化了客户端的实现;可以轻松地在工厂中添加其他类来创建其他类型的对象,而这无需更改客户端代码。最简单的情况下,客户端只需要传递一个参数就可以了;工厂还可以重用现有对象。但是,如果客户端直接创建对象的化,总是创建一个新对象。
Factory模式有3种变体:
(1)简单工厂模式: 允许接口创建对象,但不会暴露对象的创建逻辑。用来生产同一等级结构中的任意产品。(对于增加新的产品,需要修改已有代码)
(2)工厂方法模式:允许接口创建对象,但使用哪个类来创建对象,则是交由子类决定的。用来生产同一等级结构中的固定产品。(支持增加任意产品)
(3)抽象工厂模式:抽象工厂是一个能够创建一系列相关的对象而无需指定/公开其具体类的接口。该模式能够提供其他工厂的对象,在其内部创建其他对象。用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)
核心本质:
- 实例化对象,用工厂方法代替new操作。
- 将选择实现类,创建对象统一管理和控制。从而将调用者跟我们的实现类解耦。
简单工厂模式
package com.kuzma.designModel;
/*
* 简单工厂模式
*/
public class FactoryTest1 {
public static void main(String[] args) {
// 简单工厂模式
// 方式一:调用方便,不需要有调用方选择调用那个实例,只需要传入参数
CarFactory1.createCar("奥迪").run();
CarFactory1.createCar("比亚迪").run();
//c3.run();
// 方式二:
CarFactory1.createAudi().run();
CarFactory1.createByd().run();
}
}
interface Car {
void run();
}
class Audi implements Car {
@Override
public void run() {
System.out.println("奥迪行驶中");
}
}
class Byd implements Car {
@Override
public void run() {
System.out.println("比亚迪行驶中");
}
}
class CarFactory1 {
// 方式一:
public static Car createCar(String type) {
if("奥迪".equals(type)){
return new Audi();
} else if("比亚迪".equals(type)){
return new Byd();
} else {
return null;
}
}
// 方式二:
public static Car createAudi(){
return new Audi();
}
public static Car createByd(){
return new Byd();
}
}
运行结果:
奥迪行驶中
比亚迪行驶中
奥迪行驶中
比亚迪行驶中
注:
- 简单工厂模式也叫做静态工厂模式,就是工厂类一般使用静态方法,通过接收的参数的不同来返回不同的对象实例。
- 对于增加新产品无能为力,不修改代码的话是无法扩展的。
工厂方法模式
package com.kuzma.designModel;
/*
* 工厂方法模式
*
*
*/
public class FactoryTest2 {
public static void main(String[] args) {
Car c1 = new AudiFactory().createCar();
Car c2 = new BydFactory().createCar();
c1.run();
c2.run();
}
}
interface CarFactory2 {
Car createCar();
}
class AudiFactory implements CarFactory2{
@Override
public Car createCar() {
return new Audi();
}
}
class BydFactory implements CarFactory2{
@Override
public Car createCar() {
return new Byd();
}
}
运行结果:
奥迪行驶中
比亚迪行驶中
注:
* 为了避免简单工厂模式的缺点,不完全满足OCP(开闭原则)。
* 工厂方法模式和简单工厂模式最大的不同在于,简单工厂模式只有一个(对于一个项目或者一个独立模块而言)工厂类,
* 而工厂方法模式有一组实现了相同接口的工厂类。
抽象工厂模式
用于生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)
抽象工厂模式是工厂方法模式的升级版本,在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。
package com.kuzma.designModel;
/*
* 抽象工厂模式
*
*
*/
public class FactoryTest3 {
public static void main(String[] args) {
// 高端工厂
Engine luxuryEngine = new LuxuryCarFactory().createEngine();
luxuryEngine.run();
luxuryEngine.start();
// 低端工厂
Engine lowEngine = new LowCarFactory().createEngine();
lowEngine.run();
lowEngine.start();
}
}
//发动机
interface Engine {
void run();
void start();
}
class LuxuryEngine implements Engine{
@Override
public void run() {
System.out.println("转的快");
}
@Override
public void start() {
System.out.println("启动快。可以自动启停");
}
}
//工厂
interface CarFactory {
Engine createEngine();
Seat createSeat();
Tyre createTyre();
}
class LowEngine implements Engine{
@Override
public void run() {
System.out.println("转的慢");
}
@Override
public void start() {
System.out.println("启动慢");
}
}
//座椅
interface Seat {
void massage();
}
class LuxurySeat implements Seat{
@Override
public void massage() {
System.out.println("可以自动按摩");
}
}
class LowSeat implements Seat{
@Override
public void massage() {
System.out.println("不能按摩");
}
}
//轮胎
interface Tyre {
void revolve();
}
class LuxuryTyre implements Tyre {
@Override
public void revolve() {
System.out.println("旋转不磨损。");
}
}
class LowTyre implements Tyre {
@Override
public void revolve() {
System.out.println("旋转磨损快。");
}
}
//高端产品族工厂
class LuxuryCarFactory implements CarFactory{
@Override
public Engine createEngine() {
return new LuxuryEngine();
}
@Override
public Seat createSeat() {
return new LuxurySeat();
}
@Override
public Tyre createTyre() {
return new LuxuryTyre();
}
}
//低端产品族工厂
class LowCarFactory implements CarFactory {
@Override
public Engine createEngine() {
return new LowEngine();
}
@Override
public Seat createSeat() {
return new LowSeat();
}
@Override
public Tyre createTyre() {
return new LowTyre();
}
}
运行结果:
转的快
启动快。可以自动启停
转的慢
启动慢
注:抽象工厂模式,通过不同的产品族创建产品。
应用场景:
JDK
中Calendar
的getInstance
方法JDBC
中Connection
对象的获取Hibernate
中SessionFactory
创建Session
spring
中IOC
容器创建管理bean
对象XML
解析时的DocumentBuilderFactory
创建解析器对象- 反射中
Class
对象的newInstance()