设计模式之工厂模式

来源:互联网 发布:ca证书网络检测不通过 编辑:程序博客网 时间:2024/05/22 02:28

1、核心本质:

-实例化对象,用工厂方法代替new操作。
-将选择实现类、创建对象统一管理和控制,从而将调用者跟我们的实现类解耦。

2、应用场景

-JDK中Calendar的getInstance方法
-JDBC中Connection对象的获取
-Hibernate中SessionFactory创建Session
-spring中IOC容器创建管理bean对象
-XML解析时的DocumentBuilderFactory创建解析器对象
-反射中Class对象的newInstance()

3、优点

实现了创建者和调用者的分离。

4、分类

-简单工厂模式-工厂方法模式-抽象工厂模式

5、代码示例

问题引出:这里用一个射击游戏做例子,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武器、赛斯角色、防弹衣,直接增加一个工厂实现类就可以了。但是如果增加一种产品的话,就无能为力了,比如增加一个近身武器产品(即近身武器接口),有两种近身武器斧头和小刀(即两个实现类),高端玩家配备斧头,低端玩家配备小刀,那么所有的工厂类都得修改。

6、分析

1)简单工厂模式:

a、简单工厂模式也叫静态工厂模式,就是工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。
b、对于增加新产品无能为力!不修改代码的话,是无法扩展的。

2)工厂方法模式:

a、为了避免简单工厂模式的缺点,不完全满足OCP。
b、工厂方法模式和简单工厂模式最大的不同在于,简单工厂模式只有一个(对于一个项目或者一个独立模块而言)工厂类,而工厂方法模式有一组实现了相同接口的工厂类。

3)抽象工厂模式:

a、用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)
b、抽象工厂模式是工厂方法模式的升级版本,在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。

7、总结

a、简单工厂和工厂方法相比,简单工厂模式用的较多。对于我们普通 的项目来说,修改少量代码是可以接受的,而且将创建类放在一个工厂类中完成;而虽然工厂方法模式遵循面向对象设计原则,但会增加复杂度,并且导致类的数量膨胀。
b、抽象工厂模式解决增加产品族的问题,但对于增减新的产品无能为力。

0 0
原创粉丝点击