工厂模式

本次主要讲述三个内容:

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

依赖倒置原则

设计原则:要依赖抽象,不要依赖具体类。

不能让高层组件依赖底层组件,而且,不管高层或底层组件,“两者”都应该依赖于抽象。
这个原则告诉我们,应该重写代码以便于我们依赖抽象类,而不依赖具体类。

指导方针:

  • 变量不可以持有具体类的引用。(如果使用new,就会持有具体类的引用。你可以改用工厂类避开这样的做法。)
  • 不要让类派生自具体类。(如果派生自具体类,你就会依赖具体类。请派生自一个抽象(接口或抽象类))
  • 不要覆盖基类中已实现的方法。(如果覆盖基类已经实现的方法,那么你的基类将就不是一个真正适合被继承的抽象。基类中已实现的方法,应该由所有的子类共享)

简单工厂模式

简单工厂模式不是一个“真正的”设计模式,只能说是一种编程习惯。
比如建立一个抽象类Car,然后用子类来继承。用SimpleCarFactory来生成对象(里面包含选择相应对象的逻辑处理),CarStrore直接调用SimpleCarFactory即可。

如上图所示。
代码实现如下:
Car :

package com.bestqiang.easyfactory;/*** @author BestQiang*/
public abstract class Car {private String color;private String price;private String speed;public abstract void go();public abstract void clear();@Overridepublic String toString() {return "Car{" +"color='" + color + '\'' +", price='" + price + '\'' +", speed='" + speed + '\'' +'}';}public void sayHello() {System.out.println("我是" + color + "汽车," + " 我的价格是: " + price + "," + "速度是:"+ speed);}public String getSpeed() {return speed;}public void setSpeed(String speed) {this.speed = speed;}public String getColor() {return color;}public String getPrice() {return price;}public void setColor(String color) {this.color = color;}public void setPrice(String price) {this.price = price;}
}

BlueCar:

package com.bestqiang.easyfactory;/*** @author BestQiang*/
public class BlueCar extends Car {public BlueCar() {super("blue","2000$", "888km/s");}@Overridepublic void go() {System.out.println("蓝汽车清洗完成了!");}@Overridepublic void clear() {System.out.println("蓝汽车可以开走了!");}
}

RedCar:

package com.bestqiang.easyfactory;/*** @author BestQiang*/
public class RedCar extends Car {public RedCar() {super("red","1000$", "999km/s");}@Overridepublic void go() {System.out.println("红汽车可以开走了!");}@Overridepublic void clear() {System.out.println("红汽车清洗完成了!");}
}

SimpleFactory:

package com.bestqiang.easyfactory;/*** @author BestQiang*/
public class SimpleCarFactory {public Car createCar(String type) {Car car = null;if(type.equals("red")) {return new RedCar();} else if (type.equals("blue")) {return new BlueCar();}return car;}
}

CarStore:

package com.bestqiang.easyfactory;/*** @author BestQiang*/
public class CarStore {SimpleCarFactory simpleCarFactory = new SimpleCarFactory();public Car orderCar(String type) {Car car = simpleCarFactory.createCar(type);car.sayHello();car.clear();car.go();return car;}
}

Main:

package com.bestqiang.easyfactory;/*** @author BestQiang*/
public class Main {public static void main(String[] args) {// 没有依赖抽象类,下面的工厂模式会对其改进CarStore carStore = new CarStore();Car blue = carStore.orderCar("blue");Car red = carStore.orderCar("red");System.out.println(blue);System.out.println(red);}
}

运行结果:

我是blue汽车, 我的价格是: 2000$,速度是:888km/s
蓝汽车可以开走了!
蓝汽车清洗完成了!
我是red汽车, 我的价格是: 1000$,速度是:999km/s
红汽车清洗完成了!
红汽车可以开走了!
Car{color='blue', price='2000$', speed='888km/s'}
Car{color='red', price='1000$', speed='999km/s'}Process finished with exit code 0

工厂方法模式

刚才的简单工厂模式,只有一个工厂,不能动态的切换工厂。
所有的工厂模式都用来封装对象的创建。工厂方法模式(Factory Method Pattern)通过让子类决定该创建的对象是什么,来达到将对象创建的过程封装的目的。

简单工厂把全部的事情,在一个地方都处理完了,然而工厂方法却是创建一个框架,让子类决定要如何实现。等于说是
如下图所示:

简单工厂的做法,可以将对象的创建封装起来,但是简单工程不具备工厂方法的弹性,因为简单工厂不能变更正在创建的产品。Main新建工厂的时候直接new抽象类就ok了。

工厂类的实现代码:
CarStoreF:

package com.bestqiang.factory;import com.bestqiang.easyfactory.Car;
import com.bestqiang.easyfactory.SimpleCarFactory;/*** @author BestQiang*/
public abstract class CarStoreF {public Car orderCar(String type) {Car car = createCar(type);car.sayHello();car.clear();car.go();return car;}protected abstract Car createCar(String type);}

HuaweiCarStore:

package com.bestqiang.factory;import com.bestqiang.easyfactory.BlueCar;
import com.bestqiang.easyfactory.Car;
import com.bestqiang.easyfactory.RedCar;/*** @author BestQiang*/
public class HuaweiCarStore extends CarStoreF {@Overrideprotected Car createCar(String type) {Car car = null;if(type.equals("red")) {System.out.println("Huawei出品");return new RedCar();} else if (type.equals("blue")) {System.out.println("Huawei出品");return new BlueCar();}return car;}
}

XiaomiCarStore:

package com.bestqiang.factory;import com.bestqiang.easyfactory.BlueCar;
import com.bestqiang.easyfactory.Car;
import com.bestqiang.easyfactory.RedCar;/*** @author BestQiang*/
public class XiaomiCarStore extends CarStoreF {@Overrideprotected Car createCar(String type) {Car car = null;if(type.equals("red")) {System.out.println("小米出品");return new RedCar();} else if (type.equals("blue")) {System.out.println("小米出品");return new BlueCar();}return car;}
}

Main:

package com.bestqiang.factory;import com.bestqiang.easyfactory.Car;
import com.bestqiang.easyfactory.CarStore;/*** @author BestQiang*/
public class Main {public static void main(String[] args) {// 依赖于抽象类CarStoreF carStore = new HuaweiCarStore();Car blue = carStore.orderCar("blue");Car red = carStore.orderCar("red");System.out.println(blue);System.out.println(red);}
}

运行结果:

我是blue汽车, 我的价格是: 2000$,速度是:888km/s
蓝汽车可以开走了!
蓝汽车清洗完成了!
我是red汽车, 我的价格是: 1000$,速度是:999km/s
红汽车清洗完成了!
红汽车可以开走了!
Car{color='blue', price='2000$', speed='888km/s'}
Car{color='red', price='1000$', speed='999km/s'}Process finished with exit code 0

抽象工厂模式

抽象工程模式: 提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

抽象工厂允许客户使用抽象的接口来创建一组相关的产品,而不需要知道(或关心)实际产出的具体产品是什么。这样一来,客户就从具体的产品中被解耦。

抽象工厂定义了一个接口,所有的具体工程都必须实现此接口,这个接口包含一组方法用来生产产品。
当要创建产品家族和想让制造的相关产品集合起来时,可以使用抽象工厂。

可以这样理解,现在汽车工厂只生产汽车,现在如果还想生产手机,再继承原来汽车的抽象类,复用抽象类的已有的方法,实现抽象方法,就不合适了。那就建立一个抽象工厂,而且把抽象工厂设置为接口,把所有涉及的产品都写进去,然后后面再实现这个接口。
又可以这样理解,抽象工厂比工厂模式高一个级别,抽象工厂在乎的是生产的汽车还是手机,而工厂模式在乎的是生产的手机是什么样子的。在确定生产什么以后,工厂模式往往隐含在抽象工厂中。

下图中新增一个手机类,然后使用抽象工厂进行创建。

实现代码如下:
Phone:

package com.bestqiang.AFactory;/*** @author BestQiang*/
public abstract class Phone {private int color;private int price;@Overridepublic String toString() {return "Phone{" +"color=" + color +", price=" + price +'}';}public int getColor() {return color;}public void setColor(int color) {this.color = color;}public int getPrice() {return price;}public void setPrice(int price) {this.price = price;}protected abstract void call();
}

HuaweiPhone:

package com.bestqiang.AFactory;/*** @author BestQiang*/
public class HuaweiPhone extends Phone {@Overrideprotected void call() {System.out.println("华为,非一般的感觉!");}
}

XiaomiPhone:

package com.bestqiang.AFactory;/*** @author BestQiang*/
public class XiaomiPhone extends Phone {@Overrideprotected void call() {System.out.println("小米,永不止步!");}
}

Factory:

package com.bestqiang.AFactory;import com.bestqiang.easyfactory.Car;/*** @author BestQiang*/
public abstract class Factory {public abstract Phone phoneFactory(String type);public abstract Car carFactory(String type);
}

FactoryA:

package com.bestqiang.AFactory;import com.bestqiang.easyfactory.BlueCar;
import com.bestqiang.easyfactory.Car;
import com.bestqiang.easyfactory.RedCar;/*** @author BestQiang*/
public class FactoryA extends Factory {@Overridepublic Phone phoneFactory(String type) {if(type.equals("huawei")) {print();return new HuaweiPhone();} if (type.equals("XiaomiPhone")) {print();return new XiaomiPhone();}return null;}@Overridepublic Car carFactory(String type) {if(type.equals("red")) {print();return new RedCar();} if (type.equals("blue")) {print();return new BlueCar();}return null;}private void print() {System.out.println("A工厂出品");}
}

FactoryB:

package com.bestqiang.AFactory;import com.bestqiang.easyfactory.BlueCar;
import com.bestqiang.easyfactory.Car;
import com.bestqiang.easyfactory.RedCar;/*** @author BestQiang*/
public class FactoryB extends Factory {@Overridepublic Phone phoneFactory(String type) {if(type.equals("huawei")) {print();return new HuaweiPhone();} if (type.equals("XiaomiPhone")) {print();return new XiaomiPhone();}return null;}@Overridepublic Car carFactory(String type) {if(type.equals("red")) {print();return new RedCar();} if(type.equals("blue")) {print();return new BlueCar();}return null;}private void print() {System.out.println("B工厂出品");}
}
package com.bestqiang.AFactory;import com.bestqiang.easyfactory.Car;/*** @author BestQiang*/
public class Main {public static void main(String[] args) {Factory factory = new FactoryA();Car red = factory.carFactory("red");System.out.println(red);}
}

运行结果:

A工厂出品
Car{color='red', price='1000$', speed='999km/s'}Process finished with exit code 0

三种工厂模式算是介绍完了,总结一下,

  • 简单工厂模式不能动态切换工厂,不依赖与抽象。
  • 工厂方法模式创建一个抽象的工厂类,子类进行继承实现,可以动态切换工厂,适合同一种类。
  • 抽象工厂模式把多个工厂隐含在里面,可以把相关的产品集合起来。是工厂模式的升级。

HeadFirst设计模式-工厂模式(基于汽车工厂和手机工厂)相关推荐

  1. 为什么工厂模式是华而不实的——浅谈工厂模式的利与弊

    转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/17428923 说明:博主虚心接受大家的抨击,批评,指正 前言 我一直想介绍下 ...

  2. 为什么工厂模式是华而不实的—浅谈工厂模式的利与弊

    转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/17428923 说明:博主虚心接受大家的抨击,批评,指正 前言 我一直想介绍下 ...

  3. 工厂模式详解(简单工厂模式,工厂方法模式,抽象工厂模式,只给出抽象工厂模式具体代码)

    1.简单工厂模式(Factory) 应用场景:又叫做静态工厂方法(StaticFactory Method)模式,但不属于 23 种设计模式之一.简单工厂模式的实质是由一个工厂类根据传入的参数,动态决 ...

  4. 抽象工厂模式(三):抽象工厂模式概述

    3 抽象工厂模式概述 抽象工厂模式为创建一组对象提供了一种解决方案.与工厂方法模式相比,抽象工厂模式中的具体工厂不只是创建一种产品,它负责创建一族产品.抽象工厂模式定义如下:        抽象工厂模 ...

  5. lg显示器工厂模式怎么进入_LG液晶显示器进入工厂模式方法.doc

    LG液晶显示器进入工厂模式方法 常见CRT显示器的工厂模式进入方法 IT.SOHU.COM 2004-05-07 09:51 转自: 天极网 显示器工厂模式的进入方法集锦 1.TCL显示器 1)M15 ...

  6. 【设计模式-手写源码-附1】-简单工厂模式-基于魔兽争霸冰封王座

    1:主题拆解 ①依赖倒置原则-SimpleFactory ②简单工厂+ 配置文件=可配置 ③简单工厂+ 配置文件+反射=可配置可扩展 ④简单工厂升级IOC控制反转 2:基本介绍 ①学习设计模式的套路: ...

  7. JAVA设计模式是个什么玩意儿_00_工厂模式家族准备篇_简单工厂模式

    1. 前言 又叫静态工厂方法(Static Factory Method)模式. 它并不是GoF那23种设计模式之一. 简单工厂模式是工厂模式家族中最简单实用的模式. 虽然很简单,但它是学习工厂方法模 ...

  8. HeadFirst设计模式(模式总览速查)

    本文用于记录本人阅读完HeadFirst设计模式一书后对此书的总结,总结系个人理解并简化提炼,方便使用设计模式时速查,如有错漏,请积极指出,本人将虚心接受并及时改正. 1. 策略模式 1.1 使用前提 ...

  9. python工厂模式 取代__init___浅析Python 简单工厂模式和工厂方法模式的优缺点

    前言 在<设计模式>一书中工厂模式提到了: 工厂方法模式(Factory Method) 抽象工厂模式 (Abstract Factory) 但是在实际过程中还有一种工厂模式经常被使用,那 ...

  10. 工厂模式C++实现(三种工厂模式附详细注释)

    工厂模式(统称) 工厂模式是一种创建型模式,适用场景:安全的创建对象. 简单工厂模式 顾名思义,工厂是用来生产东西的,而在C++里面就是用来生产对象的. 就像一家餐厅一样,你可以按照你的方式来点餐.在 ...

最新文章

  1. java 行为模式_java设计模式--行为模式
  2. 《易学Python》——1.8 总结
  3. MyBatis子查询
  4. PageHelper分页插件的原理是什么
  5. 【玩转MLS系列】基础教程
  6. mysql与串口通信_串口通信 - ShawnXie - 博客园
  7. [目标检测]YOLO原理
  8. 江小白包装设计原型_江小白的跨界营销,系列设计很“牛啤”!
  9. roc-auc_AUC-ROC技术的局限性
  10. c51单片机学习笔记-LED闪烁编程
  11. UPS电源知识(开发板销售http://huarm.taobao.com/ )
  12. 【前端工程化】搭建vue-cli + cesium项目的脚手架及常见问题
  13. 马云将成全球第11大富豪,很好奇第一位是谁?
  14. 投资组合 有效边界的求解 matlab,Markowitz投资组合有效边界的实现——基于Matlab的实例分析...
  15. 深度学习Caffe实战笔记(6)Windows caffe平台用Siamese网络跑自己的数据
  16. 忙里偷闲【mark】
  17. 分享灵动微电子低功耗单片机MM32L系列
  18. 数据结构:树与二叉树(一) 树的基本知识
  19. 在大数据时代,如何运用数据驱动HR人才管理
  20. VBA 根据日期筛选数据

热门文章

  1. 宏碁电脑重装win10系统教程,宏碁怎么重装系统win10
  2. 不用爬虫也可以轻松获取 unsplash 图片
  3. 数据中台漫谈 — 数据接入
  4. fpu测试_「正点原子NANO STM32开发板资料连载」第三十一章 FPU 测试实验
  5. UV Mapping(UV贴图)
  6. python format是什么意思_python的format什么意思
  7. shadowmap的原理与实现
  8. 网上流行护眼色的RGB值和颜色代码汇总
  9. 信息系统项目管理师必背核心考点(四十八)合同类型的选择
  10. VISUAL STUDIO INSTALLER下载速度过慢的解决办法