23种设计模式—— 工厂设计模式
2018-03-09 17:35
78 查看
定义:
定义了一个创建产品对象的工厂接口,将实际创建工作推迟到子类工厂当中。场景模拟:
一个面条项目的方案设计 面条项目:要方便面条品种的扩展,要便于维护,要能运行时扩展
面条类设计:
面条工厂设计:if....else if....else
一、普通oop设计方式
/* * 面条父类 */ public abstract class Noodles { // 面条名称 String name; // 每种面条制作方式不同,声明为抽象方法 public abstract void make(); // 模拟定义为每种面条打包方式一致 public void box() { System.out.println(name + " 打包;"); } } /* * 麻辣面 */ public class MLNoodles extends Noodles { @Override public void make() { this.name = "麻辣面"; System.out.println(name + "制作;"); } } /* * 牛肉面 */ public class BeefNoodles extends Noodles { @Override public void make() { this.name = "牛肉面"; System.out.println(name + "制作;"); } } /* * 兰州拉面 */ public class LZNoodles extends Noodles { @Override public void make() { this.name = "兰州拉面"; System.out.println(name + "制作;"); } } /* * 面条订单 */ public class OrderNoodles { public OrderNoodles() { Noodles noodles = null; String ordertype; do { ordertype = gettype(); if (ordertype.equals("ml")) { // 选择了麻辣面 noodles = new MLNoodles(); } else if (ordertype.equals("beef")) { // 选择了牛肉面 noodles = new BeefNoodles(); } else if (ordertype.equals("lz")) { // 选择了兰州拉面 noodles = new LZNoodles(); } else { break; } noodles.box(); } while (true); } private String gettype() { //接收用户选择 Scanner scan = new Scanner(System.in); System.out.println("请选择您要点的面"); String str = scan.next(); return str; } } /* * 主方法测试 */ public class NoodlesStroe { public static void main(String[] args) { OrderNoodles orderNoodles; orderNoodles = new OrderNoodles(); } }
总结:
目前的需求解决了,但是一旦新增面条种类,需要修改订单部分的代码,违反了java开闭原则(Open Close Principle),不合理。
二、简单工厂模式:定义一个实例化面条的类,封装创建对象的代码
/* * 面条父类同上 */ /* * 简单工厂 */ public class SimpleNoodlesFactory { //实例化面条对象 public Noodles CreateNoodles(String ordertype) { Noodles noodles = null; if (ordertype.equals("ml")) { // 选择了麻辣面 noodles = new MLNoodles(); } else if (ordertype.equals("beef")) { // 选择了牛肉面 noodles = new BeefNoodles(); } else if (ordertype.equals("lz")) { // 选择了兰州拉面 noodles = new LZNoodles(); } return noodles; } } /* * 面条订单 */ public class OrderNoodles { SimpleNoodlesFactory simpleNoodlesFactory; public OrderNoodles(SimpleNoodlesFactory simpleNoodlesFactory) { setFactory(simpleNoodlesFactory); } public void setFactory(SimpleNoodlesFactory simpleNoodlesFactory) { Noodles noodles = null; String ordertype; this.simpleNoodlesFactory = simpleNoodlesFactory; do { ordertype = gettype(); noodles = simpleNoodlesFactory.CreateNoodles(ordertype); if (noodles != null) { noodles.make(); noodles.box(); } } while (true); } private String gettype() { //接收用户选择 Scanner scan = new Scanner(System.in); System.out.println("请选择您要点的面:"); String str = scan.next(); return str; } } /* * 主方法测试 */ public class NoodlesStroe { public static void main(String[] args) { //实例化工厂 SimpleNoodlesFactory simpleNoodlesFactory=new SimpleNoodlesFactory(); //创建订单 OrderNoodles orderNoodles; orderNoodles = new OrderNoodles(simpleNoodlesFactory); } }
总结:
解决了上个方案遗留的问题,再次新加对象种类时,无需修改订单部分代码。但项目进一步扩展,在不同地区开展加盟店,然而每个地区制作出的口味不同,进而利用工厂方法模式进行设计。
三、工厂方法模式:定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类(针对每一种产品提供一个工厂类 。通过不同的工厂实例来创建不同的产品实例)
/* * 北京牛肉面 */ public class BJBeefNoodles extends Noodles { @Override public void make() { this.name = "北京牛肉面"; System.out.println(name+"制作;"); } } /* * 北京麻辣面 */ public class BJMLNoodles extends Noodles { @Override public void make() { this.name = "北京麻辣面"; System.out.println(name+"制作;"); } } /* * 上海牛肉面 */ public class SHBeefNoodles extends Noodles { @Override public void make() { this.name = "上海牛肉面"; System.out.println(name+"制作;"); } } /* * 上海麻辣面 */ public class SHMLNoodles extends Noodles { @Override public void make() { this.name = "上海麻辣面"; System.out.println(name+"制作;"); } } /* * 工厂方法模式——抽象订单类 */ public abstract class OrderNoodles { public OrderNoodles() { Noodles noodles = null; String ordertype; do { ordertype = gettype(); noodles = createNoodles(ordertype); noodles.make(); noodles.box(); } while (true); } //实例化对象由加盟店具体实例化 abstract Noodles createNoodles(String ordertype); private String gettype() { //接收用户选择 Scanner scan = new Scanner(System.in); System.out.println("请选择您要点的面:"); String str = scan.next(); return str; } } /* * 北京订单类 */ public class BJOrderNoodles extends OrderNoodles { @Override Noodles createNoodles(String ordertype) { Noodles noodles = null; if (ordertype.equals("ml")) { noodles = new BJMLNoodles(); } else if (ordertype.equals("beef")) { noodles = new BJBeefNoodles(); } return noodles; } } /* * 上海订单类 */ public class SHOrderNoodles extends OrderNoodles { @Override Noodles createNoodles(String ordertype) { Noodles noodles = null; if (ordertype.equals("ml")) { noodles = new SHMLNoodles(); } else if (ordertype.equals("beef")) { noodles = new SHBeefNoodles(); } return noodles; } } /* * 主方法测试 */ public class NoodlesStroe { public static void main(String[] args) { OrderNoodles orderNoodles; orderNoodles = new SHOrderNoodles(); } }
总结:
此次改进后,只需在主方法中实例化不同的OrderNoodles对象,就可以体验不同地区的Noodles。
四、抽象工厂模式:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类(抽象工厂往往有多种方法,可以生产多种产品,即产品簇,比如工厂还可以生产饼,汤等等)。
/* * 抽象工厂 */ public interface AbsFactory { public Noodles CreateNoodles(String ordertype) ; } /* * 北京工厂 */ public class BJFactory implements AbsFactory { @Override public Noodles CreateNoodles(String ordertype) { Noodles noodles = null; if (ordertype.equals("ml")) { noodles = new BJMLNoodles(); } else if (ordertype.equals("beef")) { noodles = new BJBeefNoodles(); } return noodles; } } /* * 上海工厂 */ public class SHFactory implements AbsFactory { @Override public Noodles CreateNoodles(String ordertype) { Noodles noodles = null; if (ordertype.equals("ml")) { noodles = new SHMLNoodles(); } else if (ordertype.equals("beef")) { noodles = new SHBeefNoodles(); } return noodles; } } /* * 抽象工厂模式——订单类 */ public class OrderNoodles { AbsFactory mFactory; public OrderNoodles(AbsFactory mFactory) { setFactory(mFactory); } public void setFactory(AbsFactory mFactory) { Noodles noodles = null; String ordertype; this.mFactory = mFactory; do { ordertype = gettype(); noodles = mFactory.CreateNoodles(ordertype); if (noodles != null) { noodles.make(); noodles.box(); } } while (true); } private String gettype() { //接收用户选择 Scanner scan = new Scanner(System.in); System.out.println("请选择您要点的面:"); String str = scan.next(); return str; } } /* * 主方法测试 */ public class NoodlesStroe { public static void main(String[] args) { OrderNoodles orderNoodles; orderNoodles = new OrderNoodles(new BJFactory()); } }
抽象工厂模式与工厂方法模式的区别:
抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象。他与工厂方法模式的区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构。在编程中,通常一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类。适用场景:
无论是简单工厂模式,工厂方法模式还是抽象工厂模式,它们都具有类似的特性,适用场景也十分类似。他们的最终目的都是为了解耦。在使用时,我们不必去在意这个模式到底工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。经常你会发现,明明使用的工厂方法模式,当新需求来临,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了;而对于抽象工厂模式,当减少一个方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。所以,在使用工厂模式时,只需要关心降低耦合度的目的是否达到了。使用工厂方法后,调用端的耦合度大大降低了。并且对于工厂来说,是可以扩展的,以后如果想组装其他的产品,只需要再增加一个工厂类的实现就可以。无论是灵活性还是稳定性都得到了极大的提高。
9a06
相关文章推荐
- Java23种设计模式之-----简单工厂模式
- [设计模式之禅读书笔记]009_23种设计模式三:抽象工厂方法
- 23种设计模式之工厂模式(Factory)
- java 23种设计模式--工厂模式(factory)
- 23种设计模式之工厂方法
- 23种设计模式C++实例之工厂方法模式
- 23种设计模式(2):工厂方法模式
- 23种设计模式之工厂方法模式
- 设计模式之禅—23种设计模式详解_2 工厂模式
- 【23种设计模式】创建型模式 > 三个工厂模式(简单工厂、抽象工厂、工厂方法)
- 23种设计模式之-----简单工厂(静态工厂)模式(SimpleFactory Pattern)
- 重头开始学23种设计模式:三大工厂(简单工厂,工厂方法,抽象工厂)
- 23种设计模式(2):工厂方法模式
- 23种设计模式之——简单工厂方法模式
- 23种设计模式——工厂模式
- 23种设计模式之工厂模式
- Java23种设计模式:工厂模式(二)
- Java的23种设计模式----工厂模式
- Java 23种设计模式之简单工厂模式
- 工厂方法模式GoF23种设计模式之创建型模式之工厂方法模式