-实例化对象,用工厂方法代替new操作。
-将选择实现类、创建对象统一管理和控制,从而将调用者跟我们的实现类解耦。
-JDK中Calendar的getInstance方法
-JDBC中Connection对象的获取
-Hibernate中SessionFactory创建Session
-spring中IOC容器创建管理bean对象
-XML解析时的DocumentBuilderFactory创建解析器对象
-反射中Class对象的newInstance()
实现了创建者和调用者的分离。
-简单工厂模式
-工厂方法模式
-抽象工厂模式
问题引出:这里用一个射击游戏做例子,CF中有各种不同的枪械,我们如何创造出不同的枪械呢?
/**
* 抽象接口:武器
* @author ly1
*
*/
public interface Weapon {
void shot();
}
/**
* 武器实现类:AK
* @author ly1
*
*/
public class AK implements Weapon{
@Override
public void shot() {
System.out.println("AK后坐力大...");
}
}
/**
* 武器实现类:M4
* @author ly1
*
*/
public class M4 implements Weapon{
@Override
public void shot() {
System.out.println("M4后坐力小...");
}
}
/**
* 客户端调用
* @author ly1
*
*/
public class Client {
public static void main(String[] args) {
Weapon w1 = new AK();
Weapon w2 = new M4();
w1.shot();
w2.shot();
}
}
普通方法不使用工厂类,使得调用类与每个类之间耦合很高。
/**
* 抽象接口:武器
* @author ly1
*
*/
public interface Weapon {
void shot();
}
/**
* 武器实现类:AK
* @author ly1
*
*/
public class AK implements Weapon{
@Override
public void shot() {
System.out.println("AK后坐力大...");
}
}
/**
* 武器实现类:M4
* @author ly1
*
*/
public class M4 implements Weapon{
@Override
public void shot() {
System.out.println("M4后坐力小...");
}
}
/**
* 武器工厂类
* @author ly1
*
*/
public class WeaponFactory {
public static Weapon create(String type){
if(type.equals("M4")){
return new M4();
}else if(type.equals("AK")){
return new AK();
}else{
return null;
}
}
}
/**
* 客户端调用
* @author ly1
*
*/
public class Client {
public static void main(String[] args) {
Weapon w1 = WeaponFactory.create("AK");
Weapon w2 = WeaponFactory.create("M4");
w1.shot();
w2.shot();
}
}
简单工厂模式,在普通模式的基础上增加了工厂类,实现了创建者与调用者的分离。生产枪械集中在工厂类中完成,调用者只需通过传参完成类的创建,如果增加一种枪械,直接增加一个Weapon实现类,修改工厂类中少量代码就行了。
/**
* 抽象接口:武器
* @author ly1
*
*/
public interface Weapon {
void shot();
}
/**
* 武器实现类:AK
* @author ly1
*
*/
public class AK implements Weapon{
@Override
public void shot() {
System.out.println("AK后坐力大...");
}
}
/**
* 武器实现类:M4
* @author ly1
*
*/
public class M4 implements Weapon{
@Override
public void shot() {
System.out.println("M4后坐力小...");
}
}
/**
* 抽象工厂接口
* @author ly1
*
*/
public interface WeaponFactory {
Weapon createWeapon();
}
/**
* 工厂的实现类:AK工厂
* @author ly1
*
*/
public class AKFactory implements WeaponFactory{
@Override
public Weapon createWeapon() {
return new AK();
}
}
/**
* 工厂的实现类:M4工厂
* @author ly1
*
*/
public class M4Factory implements WeaponFactory{
@Override
public Weapon createWeapon() {
return new M4();
}
}
/**
* 客户端调用
* @author ly1
*
*/
public class Client {
public static void main(String[] args) {
Weapon w1 = new AKFactory().createWeapon();
Weapon w2 = new M4Factory().createWeapon();
w1.shot();
w2.shot();
}
}
工厂方法模式符合面向对象的OCP(Open-Closed Principle,开闭原则),可以看做简单工厂模式的升级版。当增加一种新枪械的时候,不用修改已有的代码,直接增加一个Weapon实现类和一个WeaponFactory实现类即可。当然,也造成了类的数量的膨胀和调用的复杂性,随着枪械种类的增加,类的数量急剧增加,复杂度也随之增加。
抽象工厂模式:
问题变化:生产的不光有武器,还有角色、道具,然后有几种系列(即后面提到的产品族,也就是前面几种产品的组合),比如说为高端玩家生产高端武器系列,为低端玩家生产低端武器系列。
/**
* 武器抽象接口
* @author ly1
*
*/
public interface Weapon {
void shot();
}
/**
* 武器实现类:AK
* @author ly1
*
*/
class AK implements Weapon{
@Override
public void shot() {
System.out.println("AK威力大...");
}
}
/**
* 武器实现类:M4
* @author ly1
*
*/
class M4 implements Weapon{
@Override
public void shot() {
System.out.println("M4威力小...");
}
}
/**
* 角色抽象接口
* @author ly1
*
*/
public interface Role {
void property();
}
/**
* 角色实现类:赛斯
* @author ly1
*
*/
class Sise implements Role{
@Override
public void property() {
System.out.println("我是赛斯,没有特殊属性!");
}
}
/**
* 角色实现类:潘多拉
* @author ly1
*
*/
class Pandora implements Role{
@Override
public void property() {
System.out.println("我是潘多拉,身体娇小,不易被击中!");
}
}
/**
* 装备抽象接口
* @author ly1
*
*/
public interface Equipment {
void property();
}
/**
* 装备实现类:防弹衣
* @author ly1
*
*/
class Bulletproof implements Equipment{
@Override
public void property() {
System.out.println("防弹衣减小伤害...");
}
}
/**
* 装备实现类:普通衣服
* @author ly1
*
*/
class CommonClothes implements Equipment{
@Override
public void property() {
System.out.println("普通衣服无任何效果...");
}
}
/**
* 系列产品生产的抽象工厂
* @author ly1
*
*/
public interface Factory {
Weapon createWeapon();
Role createRole();
Equipment createEquipment();
}
/**
* 高端玩家系列产品生产工厂
* @author ly1
*
*/
public class GoodPlayerFactory implements Factory{
@Override
public Weapon createWeapon() {
return new AK();
}
@Override
public Role createRole() {
return new Pandora();
}
@Override
public Equipment createEquipment() {
return new Bulletproof();
}
}
/**
* 低端玩家系列产品生产工厂
* @author ly1
*
*/
public class BadPlayerFactory implements Factory{
@Override
public Weapon createWeapon() {
return new M4();
}
@Override
public Role createRole() {
return new Sise();
}
@Override
public Equipment createEquipment() {
return new CommonClothes();
}
}
/**
* 客户端调用
* @author ly1
*
*/
public class Client {
public static void main(String[] args) {
Factory good = new GoodPlayerFactory();
Weapon w = good.createWeapon();
Role r = good.createRole();
Equipment e = good.createEquipment();
w.shot();
r.property();
e.property();
}
}
抽象工厂可以说是解决另一种新问题,即解决产品族问题,也就是不同产品类型之间组合的问题,比如增加一种中端玩家产品系列,使用AK武器、赛斯角色、防弹衣,直接增加一个工厂实现类就可以了。但是如果增加一种产品的话,就无能为力了,比如增加一个近身武器产品(即近身武器接口),有两种近身武器斧头和小刀(即两个实现类),高端玩家配备斧头,低端玩家配备小刀,那么所有的工厂类都得修改。
1)简单工厂模式:
a、简单工厂模式也叫静态工厂模式,就是工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。
b、对于增加新产品无能为力!不修改代码的话,是无法扩展的。2)工厂方法模式:
a、为了避免简单工厂模式的缺点,不完全满足OCP。
b、工厂方法模式和简单工厂模式最大的不同在于,简单工厂模式只有一个(对于一个项目或者一个独立模块而言)工厂类,而工厂方法模式有一组实现了相同接口的工厂类。3)抽象工厂模式:
a、用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)
b、抽象工厂模式是工厂方法模式的升级版本,在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。
a、简单工厂和工厂方法相比,简单工厂模式用的较多。对于我们普通 的项目来说,修改少量代码是可以接受的,而且将创建类放在一个工厂类中完成;而虽然工厂方法模式遵循面向对象设计原则,但会增加复杂度,并且导致类的数量膨胀。
b、抽象工厂模式解决增加产品族的问题,但对于增减新的产品无能为力。