设计模式之 简单工厂模式
简单工厂模式基本介绍:
1:简单工厂模式时属于创建型模式,是工厂模式的一种,简单工厂模式时由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式时工厂模式家族中最简单实用的模式。
2:简单工厂模式,定义了一个创建对象的类,有这个类来封装实例化对象的行为(代码)。
3:在软件开发中,当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式。
工厂方法(FactoryMethod)模式的定义:定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。者满足创建型模式中所要求的“创建与使用相分离”的特点。
我们把被创建的对象称为“产品”,把创建产品的对象称为“工厂”。如果要创建的产品不多,只要一个工厂类就可以完成,这种模式叫“简单工厂模式”,它不属于GOF 的23种经典设计模式,他的缺点是增加新产品时会违背“开闭原则”。
本节介绍的“工厂方法模式”是对简单工厂模式的进一步抽象化,其好处是可以是使系统在不修改原来的代码的情况下引进新的产品,即满足开闭原则。
工厂模式的主要优点有:
1)用户只需要知道具体工厂的名称就可以得到所需要的产品,无需知道产品的具体创建过程。
如:你只需要知道 格力 是做空调的,小米是做手机的,但是他们怎么做到,就不需要你关心了。
2)在系统增加新产品时只需要添加具体的产品类和对应的具体工厂,无须对原工厂进行任何修改,满足开闭原则。
其缺点是:没增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。
模式的结构:
工厂方法模式的主要角色如下:
1)抽象工厂(AbstractFactory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 new Product() 来创建产品。。
2)具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
3)抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
4)具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
传统模式——案例说明:
我有一个军工企业,我们是生成军火的,我们旗下有很多工厂,能上天的有飞机导弹、能下海的有轮船、两栖登陆舰 等等。甚至 手枪、手雷我们都有工厂进行生成——吹牛又不交钱。但是在建厂的时候我并没有学习设计模式,我的工厂是这样建设的。
1)先建 几个厂 (如:飞机、大炮、手枪工厂)
2)获取订单后,通知对应的工厂进行生产和交付。
传统模式——代码展示:
/** * 飞机工厂 */ public class AircraftFactory{ /** * 生产飞机 */ public void generate(){ System.out.println("正在生产飞机..."); } /** * 交付飞机 */ void deliver() { System.out.println("正在交付飞机..."); } } /** * 大炮工厂 */ public class CannonFactory{ /** * 生产大炮 */ public void generate(){ System.out.println("正在生产大炮..."); } /** * 交付大炮 */ void deliver() { System.out.println("正在交付大炮..."); } } /** * 手枪工厂 */ public class PistolFactory { /** * 生产手枪 */ public void generate(){ System.out.println("正在生产手枪..."); } /** * 交付手枪 */ void deliver() { System.out.println("正在交付手枪..."); } } /** * 订单 */ public class Order { private String type; public Order(String type){ this.type=type; } /** * 通知 工厂生产产品,并且进行交付 */ public void notice(){ if("飞机".equals(type)){ AircraftFactory arsenal=new AircraftFactory(); //生产 arsenal.generate(); //交付 arsenal.deliver(); }else if("大炮".equals(type)){ CannonFactory arsenal=new CannonFactory(); //生产 arsenal.generate(); //交付 arsenal.deliver(); }if("手枪".equals(type)){ PistolFactory arsenal=new PistolFactory(); //生产 arsenal.generate(); //交付 arsenal.deliver(); } } } /** * 客户端,接待用户 */ public class Client { public static void main(String[] args) { //获取订单 Order order=new Order("大炮"); //通知工厂进行生产 order.notice(); } } //运行结果 正在生产大炮... 正在交付大炮...
传统模式的优缺点:
1) 优点:比较好理解,简单容易操作
2) 缺点:违反了设计模式的OCP原则,即多扩展开放,对修改关闭。即当我们给类增加新功能的时候,尽量不要修改代码,或者尽可能少修改代码。
简答工厂模式——案例说明:
由于我的公司生产的军工产品品质一致好评,获得很多企业的好评,所以订单也越来越多,慢慢发现我之前的工厂设计有问题。扩容性太差,改动配置地方太多了。
如果我要生产坦克,我不仅要建一个坦克厂,也要新增一个坦克状态。于是我找了一个懂设计模式的人帮我设计。他给我的设计方案是这样的。
每个工厂生产模式都是一样的 先进行 generate(生产) 再进行 deliver(交付) ,这里我们只要统一的管理起来就行了。
听了设计师的话,我就建立一个 兵工厂抽象类,其他工厂都先继承兵工厂,实现兵工厂的 generate() 再进行 deliver()。 到最后不论是 生产和交付,我只需要找兵工厂这个抽象类即可。
注:不一定是抽象类,接口也行。
简答工厂模式——代码展示:
/** * 兵工厂 * 抽象工厂 */ public abstract class Arsenal { /** * 生产 商品 */ abstract void generate(); /** * 交付商品 */ abstract void deliver(); } /** * 大炮工厂 */ public class CannonFactory extends Arsenal{ /** * 生产大炮 */ @Override public void generate(){ System.out.println("正在生产大炮..."); } /** * 交付大炮 */ @Override void deliver() { System.out.println("正在交付大炮..."); } } /** * 飞机工厂 */ public class AircraftFactory extends Arsenal{ /** * 生产飞机 */ @Override public void generate(){ System.out.println("正在生产飞机..."); } /** * 交付飞机 */ @Override void deliver() { System.out.println("正在交付飞机..."); } } /** * 手枪工厂 */ public class PistolFactory extends Arsenal{ /** * 生产手枪 */ @Override public void generate(){ System.out.println("正在生产手枪..."); } /** * 交付手枪 */ @Override void deliver() { System.out.println("正在交付手枪..."); } } /** * 订单 */ public class Order { private String type; public Order(String type){ this.type=type; } /** * 通知 工厂生产产品,并且进行交付 */ public Arsenal notice(){ Arsenal arsenal=null; if("飞机".equals(type)){ arsenal=new AircraftFactory(); }else if("大炮".equals(type)){ arsenal=new CannonFactory(); }if("手枪".equals(type)){ arsenal=new PistolFactory(); } return arsenal; } } /** * 客户端,接待用户 */ public class Client { public static void main(String[] args) { //获取订单 Order order=new Order("大炮"); //通知工厂进行生产 Arsenal arsenal= order.notice(); //生产 arsenal.generate(); //交付 arsenal.deliver(); } } //运行结果 正在生产大炮... 正在交付大炮...
若获取一个新订单(如坦克 订单),我们只需要这样。
/** * 坦克工厂 */ public class TankFactory extends Arsenal{ /** * 生产坦克 */ @Override public void generate(){ System.out.println("正在生产坦克..."); } /** * 交付坦克 */ @Override void deliver() { System.out.println("正在交付坦克..."); } } /** * 订单 */ public class Order { private String type; public Order(String type){ this.type=type; } /** * 通知 工厂生产产品,并且进行交付 */ public Arsenal notice(){ Arsenal arsenal=null; if("飞机".equals(type)){ arsenal=new AircraftFactory(); }else if("大炮".equals(type)){ arsenal=new CannonFactory(); }if("手枪".equals(type)){ arsenal=new PistolFactory(); }else if("坦克".equals(type)){ arsenal=new TankFactory(); } return arsenal; } } /** * 客户端,接待用户 */ public class Client { public static void main(String[] args) { //获取订单 Order order=new Order("坦克"); //通知工厂进行生产 Arsenal arsenal= order.notice(); //生产 arsenal.generate(); //交付 arsenal.deliver(); } } //运行结果 正在生产坦克... 正在交付坦克...
静态工厂模式:
简单工厂模式也叫静态方法工厂模式
就是将创建 工厂的 方法定义成了静态的方法,这样的好处就是调用方便。
代码展示
/** * 订单 */ public class Order { /** * 通知 工厂生产产品,并且进行交付 */ public static Arsenal notice(String type){ Arsenal arsenal=null; if("飞机".equals(type)){ arsenal=new AircraftFactory(); }else if("大炮".equals(type)){ arsenal=new CannonFactory(); }if("手枪".equals(type)){ arsenal=new PistolFactory(); }else if("坦克".equals(type)){ arsenal=new TankFactory(); } return arsenal; } } /** * 客户端,接待用户 */ public class Client { public static void main(String[] args) { //通知工厂进行生产 Arsenal arsenal= Order.notice("坦克"); //生产 arsenal.generate(); //交付 arsenal.deliver(); } } //运行结果 正在生产坦克... 正在交付坦克...
符合OCP 原则 :
上面的案例都不符合ocp原则(创建一个新的工厂就不应该再去动Order 类)所以我们应该这么做。通过反射机制来创建对应的对象。
这样即便有再多的订单,创建再多的工厂也不用再去关心是否有对应的状态了,也符合了ocp原则。
代码展示:
/** * 订单 */ public class Order { /** * 通知 */ public static Arsenal notice(Class clazz) { //采用反射的方式来创建对象, //符合 ocp 原则 try { return (Arsenal) clazz.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return null; } } /** * 客户端,接待用户 */ public class Client { public static void main(String[] args) { //通知工厂进行生产 Arsenal arsenal= Order.notice(TankFactory.class); //生产 arsenal.generate(); //交付 arsenal.deliver(); } } // 运行结果 正在生产坦克... 正在交付坦克...
持续更新...

浙公网安备 33010602011771号