设计模式之工厂模式
2015-10-07 09:25
344 查看
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、抽象工厂模式解决增加产品族的问题,但对于增减新的产品无能为力。
相关文章推荐
- Codeforces Round #324 (Div. 2) D. Dima and Lisa 数论 三素数定理
- 简易sniffer演示程序
- 周报
- 某自称菜鸟总结的知识点(1)
- 输出菱形
- Ios66详解之地图定位失败错误信息处理
- Android加载网络图片学习过程
- 获取一个字符串在另一个字符串中出现的次数
- easyUI resizable组件使用
- php请求API接口方法
- 用PhotoShop制作透明背景图片
- Android字体高度的研究
- 快速与MySQL交互,使用XMAPP打开MySQL数据库,并用shell进行与MySQL交互<Window 10>
- OC中的字母大小写转换
- IOS Map
- Objective-C---8---@property KVC
- 数据结构之链栈
- 重写hashCode与equals方法的作用
- Spark开发指南
- UVA OJ部分题目代码