当前位置:网站首页>工厂模式
工厂模式
2022-07-30 00:12:00 【老蛙@】
概述
工厂模式是一个创建型模式,将对象的实例化从new方式改为工厂的方法,将选择实现类,创建对象统一管理和控制,实现调用者和实现类解耦
简单工厂模式
基本介绍
- 简单工厂模式属于创建型模式,是工厂模式的一种,简单工厂模式是由一个工厂对象决定创建哪一种产品类的实例
- 简单工厂模式定义了一个创建对象的类,有这个类来封装实例化对象的行为
- 在软件开发中,如果会用到大量的创建某种、某类或者某批对象时,就会用到工厂模式
案例
假设一个披萨店项目
- 披萨种类有很多,如GreekPizza、CheesePizza等
- 披萨的制作流程有prepare、bake、cut、box
- 完成披萨的订购制作功能
传统方式
/*** * @author shaofan * @Description 未使用简单工厂模式的方式 */
public class PizzaStore {
public static void main(String[] args) {
new OrderPizza1();
}
}
abstract class Pizza{
abstract void prepare();
abstract void bake();
abstract void cut();
abstract void box();
}
class CheesePizza extends Pizza{
@Override
void prepare() {
System.out.println("CheesePizza prepare");
}
@Override
void bake() {
System.out.println("CheesePizza bake");
}
@Override
void cut() {
System.out.println("CheesePizza cut");
}
@Override
void box() {
System.out.println("CheesePizza box");
}
}
class GreekPizza extends Pizza{
@Override
void prepare() {
System.out.println("GreekPizza prepare");
}
@Override
void bake() {
System.out.println("GreekPizza bake");
}
@Override
void cut() {
System.out.println("GreekPizza cut");
}
@Override
void box() {
System.out.println("GreekPizza box");
}
}
/*** * 披萨订购 */
class OrderPizza1{
public OrderPizza1(){
Pizza pizza = null;
String orderType;
while (true){
orderType = getOrderType();
switch(orderType){
case "Cheese":
pizza = new CheesePizza();
break;
case "Greek":
pizza = new GreekPizza();
break;
default:
System.out.println("finish");
System.exit(0);
}
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
}
}
private String getOrderType(){
Scanner in = new Scanner(System.in);
System.out.println("请输入披萨种类");
return in.next();
}
}
/*** * 披萨订购 */
class OrderPizza2{
public OrderPizza2(){
Pizza pizza = null;
String orderType;
while (true){
orderType = getOrderType();
switch(orderType){
case "Cheese":
pizza = new CheesePizza();
break;
case "Greek":
pizza = new GreekPizza();
break;
default:
System.out.println("finish");
System.exit(0);
}
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
}
}
private String getOrderType(){
Scanner in = new Scanner(System.in);
System.out.println("请输入披萨种类");
return in.next();
}
}
如果需要增加一款披萨,这个时候除了扩展一个新的类继承Pizza,还需要修改Pizza的调用方OrderPizza的代码,违反了开闭原则;加上不同的店铺可能有不同的orderPizza方式,导致增加一个pizza每个OrderPizza都要修改
如果我们把创建Pizza对象封装到一个类中,当出现新的Pizza种类时,就只用修改该类;将Pizza对象的实例化和OrderPizza调用方隔离
使用简单工厂模式
/*** * @author shaofan * @Description 使用简单工厂模式的改进 */
public class PizzaStore {
public static void main(String[] args) {
new OrderPizza(new SimpleFactory()).order();
}
}
/*** * 披萨简单工厂 */
class SimpleFactory{
public Pizza createPizza(String orderType){
Pizza pizza = null;
switch(orderType){
case "Cheese":
pizza = new CheesePizza();
break;
case "Greek":
pizza = new GreekPizza();
break;
default:
System.out.println("订购失败");
return pizza;
}
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
class OrderPizza{
private SimpleFactory simpleFactory;
public OrderPizza(SimpleFactory simpleFactory) {
this.simpleFactory =simpleFactory;
}
public void setSimpleFactory(SimpleFactory simpleFactory) {
this.simpleFactory = simpleFactory;
}
public void order(){
while(true){
String orderType = getOrderType();
if(orderType.equals("exit")){
break;
}
simpleFactory.createPizza(orderType);
}
}
private String getOrderType(){
Scanner in = new Scanner(System.in);
System.out.println("请输入披萨种类");
return in.next();
}
}
abstract class Pizza{
abstract void prepare();
abstract void bake();
abstract void cut();
abstract void box();
}
class CheesePizza extends Pizza {
@Override
void prepare() {
System.out.println("CheesePizza prepare");
}
@Override
void bake() {
System.out.println("CheesePizza bake");
}
@Override
void cut() {
System.out.println("CheesePizza cut");
}
@Override
void box() {
System.out.println("CheesePizza box");
}
}
class GreekPizza extends Pizza {
@Override
void prepare() {
System.out.println("GreekPizza prepare");
}
@Override
void bake() {
System.out.println("GreekPizza bake");
}
@Override
void cut() {
System.out.println("GreekPizza cut");
}
@Override
void box() {
System.out.println("GreekPizza box");
}
}
使用一个简单工厂将对象的创建和调用分离,这样不论多少个OrderPizza类,他们都从SimpleFactory来获取Pizza,对于新增的Pizza只用修改SimpleFactory即可
工厂方法模式
基本介绍
基于简单工厂模式,可以发现是根据参数的不同来生成不同的对象实例,在扩展的时候需要修改工厂的代码,工厂方法模式旨在将不同实体的实例由不同的工厂来创建,在扩展的时候,只需要新增新的工厂和实体类,不需要修改代码
案例
/*** * @author shaofan * @Description 工厂方法模式 */
public class FactoryMethod {
public static void main(String[] args) {
new BenchCarFactory().createCar();
new TeslaCarFactory().createCar();
}
}
interface CarFactory{
Car createCar();
}
class BenchCarFactory implements CarFactory{
@Override
public Car createCar() {
return new BenchCar();
}
}
class TeslaCarFactory implements CarFactory{
@Override
public Car createCar() {
return new TeslaCar();
}
}
abstract class Car{
String name;
}
class BenchCar extends Car{
public BenchCar(){
this.name = "奔驰";
}
}
class TeslaCar extends Car{
public TeslaCar(){
this.name = "特斯拉";
}
}
实体继承一个抽象类Car,工厂也实现一个接口CarFactory,每个工厂只负责自己的这一个产品的创建,需要新增产品时,新增一个产品类和一个工厂,而不用覆盖代码
抽象工厂模式
产品等级和产品族
- 产品等级是指产品的产品的继承结构,继承自同一父类的产品属于同一等级,比如小米手机、华为手机等都继承自手机类
- 产品族是指同一个工厂生产的,位于不同产品等级结构的一组产品,比如小米路由器、小米手机,他们都会由小米工厂生产,但是一个位于手机等级,一个位于路由器等级,他们属于同一产品族,而不是同一等级
基本介绍
抽象工厂模式定义了一个interface用于创建相关或有依赖关系的产品族,而无需指明具体的类,这个创建多个等级的同族产品的工厂就是抽象工厂
案例
/*** * @author shaofan * @Description 抽象工厂模式 */
public class AbsFactory {
}
/*** * 手机等级产品 */
abstract class Phone{
abstract void start();
abstract void shutDown();
abstract void call();
}
class XiaomiPhone extends Phone{
@Override
void start() {
System.out.println("小米手机启动");
}
@Override
void shutDown() {
System.out.println("小米手机关闭");
}
@Override
void call() {
System.out.println("小米手机通话");
}
}
class HuaweiPhone extends Phone{
@Override
void start() {
System.out.println("华为手机启动");
}
@Override
void shutDown() {
System.out.println("华为手机关闭");
}
@Override
void call() {
System.out.println("华为手机通话");
}
}
/*** * 路由器等级产品 */
abstract class Router{
abstract void start();
abstract void shutDown();
abstract void setting();
}
class XiaomiRouter extends Router{
@Override
void start() {
System.out.println("小米路由器启动");
}
@Override
void shutDown() {
System.out.println("小米路由器关闭");
}
@Override
void setting() {
System.out.println("小米路由器设置");
}
}
class HuaweiRouter extends Router{
@Override
void start() {
System.out.println("华为路由器启动");
}
@Override
void shutDown() {
System.out.println("华为路由器关闭");
}
@Override
void setting() {
System.out.println("华为路由器设置");
}
}
/*** * 抽象产品工厂 */
interface AbstractFactory{
Phone createPhone();
Router createRouter();
}
class XiaomiFactory implements AbstractFactory{
@Override
public Phone createPhone() {
return new XiaomiPhone();
}
@Override
public Router createRouter() {
return new XiaomiRouter();
}
}
class HuaweiFactory implements AbstractFactory{
@Override
public Phone createPhone() {
return new HuaweiPhone();
}
@Override
public Router createRouter() {
return new HuaweiRouter();
}
}
JDK源码分析
JDK中的Calendar类中,使用到了简单工厂模式
在Calendar.getInstance()中,通过传入的时区参数,来创建不同时区的Calendar对象
总结
- 简单工厂,重点在于caller通过参数创建不同类型的对象,而不直接创建,将对象的创建和caller隔离,在扩展同等级的对象时,只需要修改创建对象的工厂即可,与caller解耦
- 工厂方法,为了保存旧代码,扩展功能时不对代码进行修改,同一等级的不同对象有自己的工厂,每个工厂只创建自己的对象,这样在扩展的时候只用创建一个工厂类和一个对象类,不用修改代码
- 抽象工厂,对具有相同特点的同一对象族进行抽象,得到的抽象工厂可以创建同一个对象族不同等级的对象,一个工厂类对应一个对象族,一个方法对应一个对象等级
边栏推荐
- Worthington Dissociation Enzymes: Trypsin and Frequently Asked Questions
- 指令集数据产品如何设计和实现报表协同系统——基于指令集物联网操作系统的工业协同制造项目开发实践
- Chinese semantic matching
- Elephant Swap:借助ePLATO提供加密市场的套利空间
- 低压差线性稳压器MPQ2013A-AEC1品牌MPS国产替代
- go语言序列化和反序列化及序列化后的json为空和json的key值大写如何改为小写问题
- 【mysql】Mysql公用表表达式with as
- 单片机开发之基本并行I/O口
- 月薪15k的阿里测试岗,面试原来这么简单
- Worthington Papain & Chymotrypsin & DNase I
猜你喜欢
随机推荐
3 tips for using hot events to create press releases?A must-see for self-media people
Types and check set (set), study T treasure code
多商户商城系统功能拆解18讲-平台端商家售后
中文语义匹配
Worthington Papain & Chymotrypsin & DNase I
KDE Frameworks 5.20.0:Plasma迎来诸多改进
“灯塔工厂”的中国路径:智造从点到面铺开
Codeforces Round #805 (Div. 3)总结
UE4 makes crosshair + recoil
2022年ps应该选择哪个版本
Mysql internal and external connections
cp强制覆盖与不覆盖拷贝方法
定时器学习
一文解答web性能优化
Adaptive feature fusion pyramid network for multi-classes agriculturalpest detection
Elephant Swap:借助ePLATO提供加密市场的套利空间
Paper Intensive Reading - YOLOv3: An Incremental Improvement
Expansion of Parallel I/O Port in Single Chip Microcomputer Development
UE4 制作十字准心+后坐力
头条号自媒体运营:如何在今日头条涨500+粉丝?








