java设计模式之工厂模式

本文深入解析工厂模式的概念,包括简单工厂、工厂模式和抽象工厂三种形式,通过游戏开发的例子,阐述了各自的特点、优缺点及适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是工厂模式?

工厂模式(Factory Pattern)属于创建型模式,它提供了一种创建对象的最佳方式。定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行

优点:

  1. 把对象的创建和使用的过程分开,对象创建和对象使用使用的职责解耦;
  2. 如果创建对象的过程很复杂,创建过程统一到工厂里管理,既减少了重复代码,也方便以后对创建过程的修改维护;
  3. 当业务扩展时,只需要增加工厂子类,符合开闭原则;

工厂模式细分为:简单工厂,工厂模式,抽象工厂

简单工厂模式

以游戏为例子,涉及四个类:GameFactory(游戏工厂类),Gameable(游戏接口),ShootGame(射击类游戏),TowerDefenceGame(塔防类游戏)

比如游戏工厂,工厂方法通过出入的参数生成生成不同产品类型的游戏

Gameable

游戏接口,提供一个校验账户信息的接口

package com.jiulu.mybatis.factory;

public class Gameable {
	
	/**
	 * 校验账号信息
	 * @param nickName
	 */
	void validateAccount(String nickName);

}

ShootGame

射击类游戏,实现Gameable接口

package com.jiulu.mybatis.factory;

public class ShootGame implements Gameable{

	@Override
	public void validateAccount(String nickName) {
		System.out.println("射击类游戏校验昵称"+ nickName);
	}

}

TowerDefenceGame

塔防类游戏,实现Gameable接口

package com.jiulu.mybatis.factory;

public class TowerDefenceGame implements Gameable{

	@Override
	public void validateAccount(String nickName) {
		System.out.println("塔防类游戏校验昵称"+ nickName);
	}

}

GameFactory

游戏工厂,封装了创建游戏对象的过程

package com.jiulu.mybatis.factory;

public class GameFactory {
	
	/**
	 * 根据传入的类型生成实例对象
	 * @param gameType
	 * @return
	 */
	public static Gameable creator(String gameType){
		Gameable gameable = null;
		if("shoot".equals(gameType)){
			gameable = new ShootGame();
		}else if("towerDefence".equals(gameType)){
			gameable = new TowerDefenceGame();
		}
		return gameable;
	}

}

测试

客户端决定实例化哪个对象

public static void main(String[] args) {
		Gameable shootGame = GameFactory.creator("shoot");
		shootGame.validateAccount("caojiulu");
		
		System.out.println("--------------");
		
		Gameable towerDefenceGame = GameFactory.creator("towerDefence");
		towerDefenceGame.validateAccount("caojiulu");
}

结果输出

射击类游戏校验昵称caojiulu
--------------
塔防类游戏校验昵称caojiulu

优点:客户端免除了直接创建产品对象的责任,而仅仅负责调用,对象创建和对象使用使用的职责解耦
缺点:不符合设计原则之单一原则和开闭原则,对于需求的扩展需要修改代码;
使用场景:对象比较单一,需求不复杂的场景

工厂模式

工厂接口(Factory):工厂接口是工厂方法模式的核心接口,调用者会直接和工厂接口交互用于获取具体的产品实现类
具体工厂类(ConcreteFactory):是工厂接口的实现类,用于实例化产品对象,不同的具体工厂类会根据需求实例化不同的产品实现类
产品接口(Product):产品接口用于定义产品类的功能,具体工厂类产生的所有产品都必须实现这个接口。调用者与产品接口直接交互,这是调用者最关心的接口
具体产品类(ConcreteProduct):实现产品接口的实现类,具体产品类中定义了具体的业务逻辑

以游戏为例子,在上面四个类的基础上修改GameFactory(游戏工厂类)为接口,新增了两个类:ShootGameFactory(射击类游戏工厂),TowerDefenceGameFactory(塔防类游戏工厂)

修改了的GameFactory

package com.jiulu.mybatis.factory;

public interface GameFactory1 {
	/*
	 * 生成实例
	 */
	Gameable creator();

}

ShootGameFactory

实现GameFactory1,重写creator()

package com.jiulu.mybatis.factory;

/**
 * 射击类游戏工厂
 * @author caojiulu
 *
 */
public class ShootGameFactory implements GameFactory1{

	@Override
	public Gameable creator() {
		// TODO Auto-generated method stub
		return new ShootGame();
	}

}

TowerDefenceGameFactory

实现GameFactory1,重写creator()

package com.jiulu.mybatis.factory;
/**
 * 塔防类游戏工厂
 * @author caojiulu
 *
 */
public class TowerDefenceGameFactory implements GameFactory1{

	@Override
	public Gameable creator() {
		// TODO Auto-generated method stub
		return new TowerDefenceGame();
	}

}

测试

package com.jiulu.mybatis.factory;

public class FactoryTest {
	public static void main(String[] args) {
		GameFactory1 shootGameFactory = new ShootGameFactory();
		Gameable shootGame = shootGameFactory.creator();
		shootGame.validateAccount("caojiulu");
		
		System.out.println("---------------------");
		GameFactory1 towerDefenceGameFactory = new TowerDefenceGameFactory();
		Gameable towerDefenceGame = towerDefenceGameFactory.creator();
		towerDefenceGame.validateAccount("caojiulu");
	}
	

}

输出

射击类游戏校验昵称caojiulu
---------------------
塔防类游戏校验昵称caojiulu

抽象工厂

抽象工厂比工厂模式更为抽象,工厂模式只生产一种产品族,而抽象工厂生产多个产品族

产品族是指同一工厂生产的一组不同产品结构的一组产品,比如射击游戏工厂生产单人射击游戏和双人射击游戏两款产品,这里的单人射击游戏产和双人射击游戏两款产品统称为产品族

以上面的游戏为例,现在有射击游戏和塔防游戏俩款游戏,现在需求变了,要求射击类游戏又细分为单人和双人两款游戏产品,塔防类游戏细分为单人和双人两款游戏产品。这时射击类游戏和塔防类游戏就是两个产品族,旗下分别有两款产品一款是单人游戏,一款是双人游戏

GameFactory

抽象工厂,规定了生成单人和双人两种游戏

package com.jiulu.mybatis.factory;

public interface GameFactory2 {
	/**
	 * 生产单个游戏
	 * @return
	 */
	Gameable2 createSingleGame();
	/**
	 * 生产双人游戏
	 * @return
	 */
	Gameable2 createDoubleGame();

}

ShootGameFactory2

具体工厂,负责生产具体的射击类单人游戏和射击类双人游戏

package com.jiulu.mybatis.factory;

/**
 * 射击类游戏工厂
 * @author caojiulu
 *
 */
public class ShootGameFactory2 implements GameFactory2{

	@Override
	public Gameable2 createSingleGame() {
		// TODO Auto-generated method stub
		return new SingleShootGame();
	}

	@Override
	public Gameable2 createDoubleGame() {
		// TODO Auto-generated method stub
		return new DoubleTowerDefenceGame();
	}

	

}

TowerDefenceGameFactory2

具体工厂,负责生产具体的塔防类单人游戏和塔防类双人游戏

package com.jiulu.mybatis.factory;
/**
 * 塔防类游戏工厂
 * @author caojiulu
 *
 */
public class TowerDefenceGameFactory2 implements GameFactory2{

	@Override
	public Gameable2 createSingleGame() {
		// TODO Auto-generated method stub
		return new SingleTowerDefenceGame();
	}

	@Override
	public Gameable2 createDoubleGame() {
		// TODO Auto-generated method stub
		return new DoubleTowerDefenceGame();
	}

}

Gameable2

抽象产品,所有游戏产品均实现该接口

package com.jiulu.mybatis.factory;

public interface Gameable2 {
	
	/**
	 * 校验账号信息
	 * @param nickName
	 */
	void validateAccount(String nickName);
	
	/**
	 * 游戏人数
	 */
	void getPlayerNumber();

}

ShootGame和TowerDefenceGame

package com.jiulu.mybatis.factory;

public abstract class ShootGame2 implements Gameable2{

	@Override
	public void validateAccount(String nickName) {
		System.out.println("射击类游戏校验昵称"+ nickName);
	}

}

 

package com.jiulu.mybatis.factory;

public abstract class TowerDefenceGame2 implements Gameable2{

	@Override
	public void validateAccount(String nickName) {
		System.out.println("塔防类游戏校验昵称"+ nickName);
	}

}

具体产品

共四款游戏产品:SingleShootGame,DoubleShootGame,SingleTowerDefenceGame,DoubleTowerDefenceGame

package com.jiulu.mybatis.factory;

public class SingleShootGame extends ShootGame2{

	@Override
	public void getPlayerNumber() {
		// TODO Auto-generated method stub
		System.out.println("这是一个单人玩的射击游戏");
	}

}
package com.jiulu.mybatis.factory;

public class DoubleShootGame extends ShootGame2{

	@Override
	public void getPlayerNumber() {
		// TODO Auto-generated method stub
		System.out.println("这是一个双人玩的射击游戏");
	}

}
package com.jiulu.mybatis.factory;

public class SingleTowerDefenceGame extends TowerDefenceGame2{

	@Override
	public void getPlayerNumber() {
		// TODO Auto-generated method stub
		System.out.println("这是一个单人玩的塔防游戏");
	}

}
package com.jiulu.mybatis.factory;

public class DoubleTowerDefenceGame extends TowerDefenceGame2{

	@Override
	public void getPlayerNumber() {
		// TODO Auto-generated method stub
		System.out.println("这是一个双人玩的塔防游戏");
	}

}

测试

package com.jiulu.mybatis.factory;

public class FactoryTest2 {
	public static void main(String[] args) {
		GameFactory2 shootGameFactory = new ShootGameFactory2();
		shootGameFactory.createSingleGame().getPlayerNumber();
		shootGameFactory.createDoubleGame().getPlayerNumber();
		System.out.println("---------------------");
		GameFactory2 towerDefenceGameFactory = new TowerDefenceGameFactory2();
		towerDefenceGameFactory.createSingleGame().getPlayerNumber();
		towerDefenceGameFactory.createDoubleGame().getPlayerNumber();
	}
	

}

输出

这是一个单人玩的射击游戏
这是一个双人玩的塔防游戏
---------------------
这是一个单人玩的塔防游戏
这是一个双人玩的塔防游戏

参考文章:https://baijiahao.baidu.com/s?id=1625606999883136508&wfr=spider&for=pc

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值