设计模式: 可以被重复利用的解决方案
GoF设计模式一共包含23种设计模式,可分为三大类:
- 创建型(5个):解决对象创建问题。
- 单例模式
- 工厂方法模式
- 抽象工厂模式
- 建造者模式
- 原型模式
- 结构型(7个):一些类或对象组合在一起的经典结构。
- 代理模式
- 装饰模式
- 适配器模式
- 组合模式
- 享元模式
- 外观模式
- 桥接模式
- 行为型(11个):解决类或对象之间的交互问题。
- 策略模式
- 模板方法模式
- 责任链模式
- 观察者模式
- 迭代子模式
- 命令模式
- 备忘录模式
- 状态模式
- 访问者模式
- 中介者模式
- 解释器模式
这里只讲工厂模式 因为Spring底层源码大量使用了工厂模式
6.1 工厂模式的三种形态
- 简单工厂模式: 不属于23种设计模式之一。简单工厂模式又叫做:静态 工厂方法模式。简单工厂模式是工厂方法模式的一种特殊实现。
- 工厂方法模式:
- 抽向工厂模式
6.2 简单工厂模式
有三个角色:
- 抽象产品角色
- 具体产品角色
- 工厂类角色
代码示例如下:
抽象产品角色:
public abstract class Weapon {
/**
* 所有的武器都有攻击行为
*/
public abstract void attack();
}
具体产品角色:
package com.powernode.factory;
/**
* 坦克(具体产品角色)
**/
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 Dagger extends Weapon{
@Override
public void attack() {
System.out.println("砍他丫的!");
}
}
工厂类角色:
/**
* 工厂类角色
**/
public class WeaponFactory {
/**
* 根据不同的武器类型生产武器
* @param weaponType 武器类型
* @return 武器对象
*/
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 if ("DAGGER".equals(weaponType)) {
weapon = new Dagger();
} else {
throw new RuntimeException("不支持该武器!");
}
return weapon;
}
}
测试程序(客户端程序) :
package com.powernode.factory;
public class Client {
public static void main(String[] args) {
Weapon weapon1 = WeaponFactory.get("TANK");
weapon1.attack();
Weapon weapon2 = WeaponFactory.get("FIGHTER");
weapon2.attack();
Weapon weapon3 = WeaponFactory.get("DAGGER");
weapon3.attack();
}
}
简单工厂模式的特点:
- 客户端程序不需要关心对象的创建细节 , 需要哪个对象就向工厂索要 , 初步实现了责任分离
简单工厂模式的缺点:
- 工厂类成了全能类(上帝类), 一旦有所问题,整个系统会瘫痪
- 不符合OCP原则,进行系统扩展的时候.需要修改工厂类
Spring中的BeanFactory就使用了简单工厂模式
6.3 工厂方法模式
保留了简单工厂模式的优点,又解决了简单模式工厂的缺点
工厂方法模式的角色包括:
- 抽象工厂角色
- 具体工厂角色
- 抽象产品角色
- 具体产品角色 (比简单工厂模式多了抽象工厂角色)
package com.factory;
/**
* 武器类(抽象产品角色)
**/
public abstract class Weapon {
/**
* 所有武器都有攻击行为
*/
public abstract void attack();
}
package com.factory;
/**
* 具体产品角色
**/
public class Gun extends Weapon{
@Override
public void attack() {
System.out.println("开枪射击!");
}
}
package com.factory;
/**
* 武器工厂接口(抽象工厂角色)
**/
public interface WeaponFactory {
Weapon get();
}
package com.factory;
/**
* 具体工厂角色
**/
public class GunFactory implements WeaponFactory{
@Override
public Weapon get() {
return new Gun();
}
}
想扩展就增加一个产品类,在增加一个对应的工厂类就好了
总结: 优点: - 一个调用者想创建一个对象,只要知道名称 - 扩展性高,不用修改之前的代码 - 屏蔽了产品的具体实现 缺点: -每次增加一个产品,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,导致系统复杂度增加
6.4抽象工厂 模式
抽象工厂模式相对于工厂方法模式来说,就是工厂方法模式是针对一个产品系列的,而抽象工厂模式是针对多个产品系列的,即工厂方法模式是一个产品系列一个工厂类,而抽象工厂模式是多个产品系列一个工厂类。
抽象工厂模式特点:抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。它有多个抽象产品类,每个抽象产品类可以派生出多个具体产品类,一个抽象工厂类,可以派生出多个具体工厂类,每个具体工厂类可以创建多个具体产品类的实例。每一个模式都是针对一定问题的解决方案,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式针对的是多个产品等级结果。
抽象工厂中包含4个角色:
- 抽象工厂角色
- 具体工厂角色
- 抽象产品角色
- 具体产品角色
抽象工厂模式的优缺点:
- 优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
- 缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在AbstractFactory里加代码,又要在具体的里面加代码。