工厂模式的三种形态: 工厂模式是解决对象创建问题的属于创建型设计模式,Spring框架底层使用了大量的工厂模式
简单/静态工厂模式
简单工厂模式的优点
消费
,工厂只负责生产
, 初步实现了责任的分离简单工厂模式的缺点
上帝类/全能类
, 显然工厂类非常关键一旦出问题整个系统将瘫痪简单工厂模式的角色包括三个:抽象产品角色
,具体产品角色
, (静态)工厂类角色(
提供创建对象的静态方法)
// 抽象产品角色: 武器
public abstract class Weapon {
// 所有的武器都有攻击行为
public abstract void attack();
}
// 具体产品角色:坦克
public class Tank extends Weapon{
@Override
public void attack() {
System.out.println("坦克开炮!");
}
}
// 具体产品角色:战斗机
public class Fighter extends Weapon{
@Override
public void attack() {
System.out.println("战斗机投下原子弹!");
}
}
//工厂类角色:根据不同的武器类型不同的生产武器
public class WeaponFactory {
// 根据不同的武器类型生产不同的武器
public static Weapon get(String weaponType){
if (weaponType == null || weaponType.trim().length() == 0) {
return null;
}
Weapon weapon = null;
if ("TANK".equals(weaponType)) {
weapon = new Tank();
} else if ("FIGHTER".equals(weaponType)) {
weapon = new Fighter();
} else {
throw new RuntimeException("不支持该武器!");
}
return weapon;
}
}
编写测试程序,通过指定武器的类型从静态工厂中获取对应的武器
public class Client {
public static void main(String[] args) {
Weapon weapon1 = WeaponFactory.get("TANK");
weapon1.attack();
Weapon weapon2 = WeaponFactory.get("FIGHTER");
weapon2.attack();
}
}
工厂方法模式
工厂方法模式既保留了简单工厂模式的优点,同时又解决了简单工厂模式的缺点
消费
,工厂只负责生产
工厂方法模式的缺点
工厂方法模式的角色包括:抽象工厂角色(生产多种武器)
, 具体工厂角色(一个工厂对应生产一种武器)
, 抽象产品角色
, 具体产品角色
//抽象工厂角色: 专门生产各种武器的工厂
public interface WeaponFactory {
Weapon get();
}
//具体工厂角色:专门生产枪的工厂
public class GunFactory implements WeaponFactory{
@Override
public Weapon get() {
return new Gun();
}
}
//具体工厂角色:专门生成飞机的工厂(工厂也可以通过简单工厂模式封装成一个大工厂,然后调用其的静态方法创建对应的工厂)
public class FighterFactory implements WeaponFactory{
@Override
public Weapon get() {
return new Fighter();
}
}
// 抽象产品角色: 武器类
public abstract class Weapon {
// 所有武器都有攻击行为
public abstract void attack();
}
// 具体产品角色:枪
public class Gun extends Weapon{
@Override
public void attack() {
System.out.println("开枪射击!");
}
}
// 具体产品角色:战斗机
public class Fighter extends Weapon{
@Override
public void attack() {
System.out.println("战斗机发射核弹!");
}
}
编写测试程序,获取对应的工厂创建对应的产品
public class Client {
public static void main(String[] args) {
// 这里的new GunFactory()可以采用简单工厂模式进行隐藏,调用WeaponFactory的静态方法根据传递的参数创建对应的工厂
WeaponFactory factory = new GunFactory();
Weapon weapon = factory.get();
weapon.attack();
WeaponFactory factory1 = new FighterFactory();
Weapon weapon1 = factory1.get();
weapon1.attack();
}
}
新增一个匕首产品类
只需要新增一个该产品对应的匕首工厂
即可
// 具体产品角色:匕首
public class Dagger extends Weapon{
@Override
public void attack() {
System.out.println("切割!");
}
}
//具体工厂角色:专门生产匕首的工厂
public class DaggerFactory implements WeaponFactory{
@Override
public Weapon get() {
return new Dagger();
}
}
// 测试生产新增的产品类
public class Client {
public static void main(String[] args) {
WeaponFactory factory2 = new DaggerFactory();
Weapon weapon2 = factory2.get();
weapon2.attack();
}
}
抽象工厂模式
工厂方法模式是针对一个产品等级结构(一个产品系列一个工厂类),而抽象工厂模式是针对多个产品等级结构(多个产品系列一个工厂类)
抽象工厂模式的优点
抽象工厂模式缺点
抽象工厂中包含4个角色:抽象工厂角色, 具体工厂角色, 抽象产品角色, 具体产品角色
抽象产品角色:武器产品族,水果产品族
public abstract class Weapon {
// 所以武器都有攻击行为
public abstract void attack();
}
public abstract class Fruit {
// 所有果实都有一个成熟周期
public abstract void ripeCycle();
}
具体产品角色:武器产品族
// 武器产品族中的产品等级1
public class Gun extends Weapon{
@Override
public void attack() {
System.out.println("开枪射击!");
}
}
// 武器产品族中的产品等级2
public class Dagger extends Weapon{
@Override
public void attack() {
System.out.println("切割!");
}
}
// 水果产品族中的产品等级1
public class Orange extends Fruit{
@Override
public void ripeCycle() {
System.out.println("橘子的成熟周期是10个月");
}
}
package com.powernode.product;
// 水果产品族中的产品等级2
public class Apple extends Fruit{
@Override
public void ripeCycle() {
System.out.println("苹果的成熟周期是8个月");
}
}
抽象工厂角色: 既能生产武器又能生产水果
public abstract class AbstractFactory {
public abstract Weapon getWeapon(String type);
public abstract Fruit getFruit(String type);
}
具体工厂角色: 武器族工厂, 水果族工厂,根据用户提供的名称创建具体的产品
// 武器族工厂
public class WeaponFactory extends AbstractFactory{
public Weapon getWeapon(String type){
if (type == null || type.trim().length() == 0) {
return null;
}
if ("Gun".equals(type)) {
return new Gun();
} else if ("Dagger".equals(type)) {
return new Dagger();
} else {
throw new RuntimeException("无法生产该武器");
}
}
@Override
public Fruit getFruit(String type) {
return null;
}
}
// 水果族工厂
public class FruitFactory extends AbstractFactory{
@Override
public Weapon getWeapon(String type) {
return null;
}
public Fruit getFruit(String type){
if (type == null || type.trim().length() == 0) {
return null;
}
if ("Orange".equals(type)) {
return new Orange();
} else if ("Apple".equals(type)) {
return new Apple();
} else {
throw new RuntimeException("我家果园不产这种水果");
}
}
}
测试程序
public class Client {
public static void main(String[] args) {
// 客户端调用方法时只面向AbstractFactory调用方法
AbstractFactory factory = new WeaponFactory();
Weapon gun = factory.getWeapon("Gun");
Weapon dagger = factory.getWeapon("Dagger");
gun.attack();
dagger.attack();
AbstractFactory factory1 = new FruitFactory();
Fruit orange = factory1.getFruit("Orange");
Fruit apple = factory1.getFruit("Apple");
orange.ripeCycle();
apple.ripeCycle();
}
}