java工厂模式实例(设计模式)
目录
java工厂模式
工厂模式其实又分为三种
1.简单工厂模式:
简单工厂模式(非静态)
简单工厂模式(静态):
2.工厂方法模式:
3.抽象工厂模式:
java工厂模式
开篇声明,此理解为作者自身理解,不一定正确,如有错误请大佬们指正。
工厂模式,在作者看来,从现实生活来说,就是一个工厂,里面有N个车间,
每个车间会生产不同的产品,而租户只需要告诉这个工厂的老板我需要一个
什么产品,老板会去找到对应的车间返回给租户使用。
画个图理解:
如果使用java语言来描述则是,对具有相同动作,不同动作执行过程的一
类方法抽象出一个接口类,然后不同的实现类对接口类中的接口进行不同的
实现,并且编写一个工厂类,根据传入获取不同的实现类实例返回给调用者,调用者使用得到的实例
执行具体的方法。画个图(简单的加减乘除做示例,没怎么画过UML图,如果有错误,请见谅):
TestServiceImpl为业务逻辑实现类,MathFactory为工厂类,MathOperation为算法抽象接口类,
xxxOpreation为算法具体实现类,Class为java原生类,主要是要使用反射机制,会用到
工厂模式其实又分为三种
1.简单工厂模式:
不提供工厂接口只有工厂,提供实例的接口与实现
简单工厂模式(非静态)
就是提供一个接口interface,然后不同的实现类实现interface,再提供一个
工厂类,在工厂类中通过if条件判断,new出具体的实现类给调用者使用。
算法抽象接口
public interface MathOperation {double apply(int a, int b);
}
算法抽象接口实现 (顺序-加减乘除):
import com.liu.test.factory.simplefactory.MathOperation;public class AddOperation implements MathOperation {@Overridepublic double apply(int a, int b) {return (double) a + b;}
}
import com.liu.test.factory.simplefactory.MathOperation;public class SubOperation implements MathOperation {@Overridepublic double apply(int a, int b) {return (double) a - b;}
}
import com.liu.test.factory.simplefactory.MathOperation;public class MultiplyOperation implements MathOperation {@Overridepublic double apply(int a, int b) {return (double) a * b;}
}
import com.liu.test.factory.simplefactory.MathOperation;public class DivideOperation implements MathOperation {@Overridepublic double apply(int a, int b) {return (double) a / b;}
}
工厂类:
import com.liu.test.factory.simplefactory.operation.AddOperation;
import com.liu.test.factory.simplefactory.operation.DivideOperation;
import com.liu.test.factory.simplefactory.operation.MultiplyOperation;
import com.liu.test.factory.simplefactory.operation.SubOperation;public class MatchFactory {/*** 获得具体的操作类型* @author kevin* @param operator :* @return java.util.Optional<com.liu.test.math.MathOperation>* @date 2021/1/25 11:36*/public static Optional<MathOperation> getOperation(String operator) {MathOperation result = null;if("add".equals(operator)){result = new AddOperation();}else if("sub".equals(operator)){result = new SubOperation();}else if("multiply".equals(operator)){result = new MultiplyOperation();}else if("divide".equals(operator)){result = new DivideOperation();}return Optional.ofNullable(result);}
}
使用类
MathOperation operation = MathFactory.getOperation(operator).orElseThrow(() ->new IllegalArgumentException("未知的操作"));result = operation.apply(first, second);return result;
简单工厂模式(静态):
就是在第一步的基础之上,将new的动作提出来,放到static块中执行,然后
将产生的实现类实例存放到静态的map中,用户调用的时候,直接从map中get对应的实例。
此模式不符合java的闭环原则(对扩展开放,对修改关闭)
静态只需调整工厂类即可,其他不变
import com.liu.test.factory.simplefactory.operation.AddOperation;
import com.liu.test.factory.simplefactory.operation.DivideOperation;
import com.liu.test.factory.simplefactory.operation.MultiplyOperation;
import com.liu.test.factory.simplefactory.operation.SubOperation;import java.lang.reflect.InvocationTargetException;
import java.util.Optional;import java.util.HashMap;
import java.util.Map;public class MatchFactory {static Map<String, MathOperation> operationMap = new HashMap<>();static {operationMap.put("add", new AddOperation());operationMap.put("sub", new SubOperation());operationMap.put("multiply", new MultiplyOperation());operationMap.put("divide", new DivideOperation());}public static Optional<Operation> getOperation(String operator) {return Optional.ofNullable(operationMap.get(operator));}
}
简单工厂模式(反射):
就是在第一步的基础之上,将new的动作去掉,换成反射的方式实现,将接口实现类统一放
在一个包中,然后统一命名规范,最后根据传入反射产生实例对象;用户调用的时候,直接传入
调用类型即可(统一实现类命名规范xxxOperation);只需调整工厂类即可,其他不变:
import java.lang.reflect.InvocationTargetException;
import java.util.Optional;/**** <p>Title:工厂类</p >* <p>ClassName:MatchFactory</p >* @author kevin* @date 2021/1/26*/
public class MathFactory {private MathFactory() {//do nothing}/*** 获得具体的操作类型* @author kevin* @param operator :* @return java.util.Optional<com.liu.test.math.MathOperation>* @date 2021/1/26 11:36*/public static Optional<MathOperation> getOperation(String operator) throws ClassNotFoundException,IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {//因为类名首字母大写,所以转换操作类型为类名格式String operate = operator.substring(0,1).toUpperCase() + operator.substring(1).toLowerCase();Class<?> operation = Class.forName("com.liu.test.math.operation." + operate+"Operation");return Optional.of((MathOperation)operation.getDeclaredConstructor().newInstance());}
}
2.工厂方法模式:
工厂提供接口与实现,实例提供接口与实现
为了解决第一种简单工厂模式的缺陷,产生了工厂方法模式,把工厂方法再次进行抽象,
为不同的实现类,提供不同的工厂,通过实现抽象工厂接口类的方法,实现不同工厂获取
业务实现类的不同实例,调用的时候,通过判断,使用不同的工厂(在简单工厂模式基础上)
抽象一个工厂接口:
import java.util.Optional;public interface MathFactoryInterface {Optional<MathOperation> getOperation(String operator) ;
}
工厂接口实现(顺序-加减乘除):
import com.liu.test.factory.simplefactory.MathOperation;
import com.liu.test.factory.factorymethod.MathFactoryInterface;
import com.liu.test.factory.simplefactory.operation.AddOperation;import java.util.Optional;public class AddFactory implements MathFactoryInterface {@Overridepublic Optional<MathOperation> getOperation() {return Optional.of(new AddOperation());}
}
import com.liu.test.factory.simplefactory.MathOperation;
import com.liu.test.factory.factorymethod.MathFactoryInterface;
import com.liu.test.factory.simplefactory.operation.SubOperation;import java.util.Optional;public class SubFactory implements MathFactoryInterface {@Overridepublic Optional<MathOperation> getOperation() {return Optional.of(new SubOperation());}
}
import com.liu.test.factory.factorymethod.MathFactoryInterface;
import com.liu.test.factory.factorymethod.operation.MultiplyOperation;
import com.liu.test.factory.simplefactory.MathOperation;import java.util.Optional;public class MultiplyFactory implements MathFactoryInterface {@Overridepublic Optional<MathOperation> getOperation() {return Optional.of(new MultiplyOperation());}
}
import com.liu.test.factory.factorymethod.MathFactoryInterface;
import com.liu.test.factory.factorymethod.operation.DivideOperation;
import com.liu.test.factory.simplefactory.MathOperation;import java.util.Optional;public class DivideFactory implements MathFactoryInterface {@Overridepublic Optional<MathOperation> getOperation() {return Optional.of(new DivideOperation());}
}
将原有的工厂类MathFactory删除,使用类中调整-增加方法:
/*** 工厂方法模式* @author kevin* @param operator :* @return com.liu.test.math.factorymethod.MathFactoryInterface* @date 2021/1/26 18:41*/private MathFactoryInterface getFactory(String operator){MathFactoryInterface result = null;if("add".equals(operator)){result = new AddFactory();}else if("sub".equals(operator)){result = new SubFactory();}else if("multiply".equals(operator)){result = new MultiplyFactory();}else if("divide".equals(operator)){result = new DivideFactory();}return Optional.ofNullable(result).orElseThrow(() -> new IllegalArgumentException("未知的操作"));}
使用类中调整-更改调用方式:
double result;MathFactoryInterface factory = getFactory(operator);MathOperation operation = factory.getOperation().orElseThrow(() ->new IllegalArgumentException("未知的操作"));result = operation.apply(first, second);return String.valueOf(result);
3.抽象工厂模式:
提供工厂的接口与实现,提供实例的接口与实现,有不同类型的实例(每个类型下有多个实例)
就是将操作归类,然后分别提供接口,同类下的具体事物实现同一个接口。然后抽象一个工厂接口,
按照不同类别,提供不同的待实现工厂方法;再提供具体的工厂实现类,实现抽象的工厂接口,并在不
同的方法(同一类事物的获取方法)中根据入参返回同类事物中具体的事物,最后给到调用者执行。
比如,阿里与百度都有开发人员与产品人员:
首先定义开发人员接口、产品人员接口:
/**** <p>Title:开发人员</p >* <p>ClassName:IDeveloper</p >* @author kevin* @date 2021/1/27*/
public interface IDeveloper {String work();String skill();
}
/**** <p>Title:产品人员</p >* <p>ClassName:IProductor</p >* @author kevin* @date 2021/1/27*/
public interface IProductor {String work();String skill();
}
开发人员接口实现:
import com.liu.test.factory.abstractfactory.cases.IDeveloper;public class AliDeveloper implements IDeveloper {@Overridepublic String work() {return "我是阿里开发人员,我的工作是:为阿里服务!";}@Overridepublic String skill() {return "我是阿里开发人员,我的技能是:java、python、vue、react、js、c、c++、c#......无所不能!";}
}
import com.liu.test.factory.abstractfactory.cases.IDeveloper;public class BaiduDeveloper implements IDeveloper {@Overridepublic String work() {return "我是百度开发人员,我的工作是:为百度服务!";}@Overridepublic String skill() {return "我是百度开发人员,我的技能是:人工智能、java、python、vue、react、js、c、c++、c#......我也无所不能!";}
}
产品人员接口实现:
import com.liu.test.factory.abstractfactory.cases.IProductor;public class AliProductor implements IProductor {@Overridepublic String work() {return "我是阿里产品,我的工作是:为阿里提供优秀的产品!";}@Overridepublic String skill() {return "我是阿里产品,我的技能是:需求与利益的平衡能力,缜密的逻辑思维和较高的业务理解能力!";}
}
import com.liu.test.factory.abstractfactory.cases.IProductor;public class BaiduProductor implements IProductor {@Overridepublic String work() {return "我是百度产品,我的工作是:为百度提供优秀的产品!";}@Overridepublic String skill() {return "我是百度产品,我的技能是:需求与利益的平衡能力,缜密的逻辑思维和较高的业务理解能力!";}
}
定义工厂接口:
import com.liu.test.factory.abstractfactory.cases.IDeveloper;
import com.liu.test.factory.abstractfactory.cases.IProductor;import java.lang.reflect.InvocationTargetException;public interface IFactory {IProductor getProductor(String type) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException,InvocationTargetException, InstantiationException;IDeveloper getDeveloper(String type) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException,InvocationTargetException, InstantiationException;
}
阿里工厂接口实现(反射获得实例):
import com.liu.test.factory.abstractfactory.IFactory;
import com.liu.test.factory.abstractfactory.cases.IDeveloper;
import com.liu.test.factory.abstractfactory.cases.IProductor;import java.lang.reflect.InvocationTargetException;
import java.util.Optional;public class AliFactory implements IFactory {@Overridepublic IProductor getProductor(String type) throws ClassNotFoundException, NoSuchMethodException,IllegalAccessException, InvocationTargetException, InstantiationException {//因为类名首字母大写,所以转换操作类型为类名格式String operate = type.substring(0,1).toUpperCase() + type.substring(1).toLowerCase();Class<?> operation = Class.forName("com.liu.test.factory.abstractfactory.cases.impl." + operate + "Productor");return Optional.of((IProductor)operation.getDeclaredConstructor().newInstance()).orElseThrow(() ->new IllegalArgumentException("未知的公司"));}@Overridepublic IDeveloper getDeveloper(String type) throws ClassNotFoundException, NoSuchMethodException,IllegalAccessException, InvocationTargetException, InstantiationException {//因为类名首字母大写,所以转换操作类型为类名格式String operate = type.substring(0,1).toUpperCase() + type.substring(1).toLowerCase();Class<?> operation = Class.forName("com.liu.test.factory.abstractfactory.cases.impl." + operate + "Developer");return Optional.of((IDeveloper)operation.getDeclaredConstructor().newInstance()).orElseThrow(() ->new IllegalArgumentException("未知的公司"));}
}
百度工厂接口实现(反射获得实例):
import com.liu.test.factory.abstractfactory.IFactory;
import com.liu.test.factory.abstractfactory.cases.IDeveloper;
import com.liu.test.factory.abstractfactory.cases.IProductor;import java.lang.reflect.InvocationTargetException;
import java.util.Optional;public class BaiduFactory implements IFactory {@Overridepublic IProductor getProductor(String type) throws ClassNotFoundException, NoSuchMethodException,IllegalAccessException, InvocationTargetException, InstantiationException {//因为类名首字母大写,所以转换操作类型为类名格式String operate = type.substring(0,1).toUpperCase() + type.substring(1).toLowerCase();Class<?> operation = Class.forName("com.liu.test.factory.abstractfactory.cases.impl." + operate + "Productor");return Optional.of((IProductor)operation.getDeclaredConstructor().newInstance()).orElseThrow(() ->new IllegalArgumentException("未知的公司"));}@Overridepublic IDeveloper getDeveloper(String type) throws ClassNotFoundException, NoSuchMethodException,IllegalAccessException, InvocationTargetException, InstantiationException {//因为类名首字母大写,所以转换操作类型为类名格式String operate = type.substring(0,1).toUpperCase() + type.substring(1).toLowerCase();Class<?> operation = Class.forName("com.liu.test.factory.abstractfactory.cases.impl." + operate + "Developer");return Optional.of((IDeveloper)operation.getDeclaredConstructor().newInstance()).orElseThrow(() ->new IllegalArgumentException("未知的公司"));}
}
通过调用不同的抽象工厂的实现获得具体的实例,执行方法得到想要的结果。
String result = "";//获得具体的工厂(反射)String operate = operator.substring(0,1).toUpperCase() + operator.substring(1).toLowerCase();Class<?> operation = Class.forName("com.liu.test.factory.abstractfactory.factory." + operate + "Factory");IFactory factory = (IFactory)operation.getDeclaredConstructor().newInstance();//通过工厂获得公司开发人员IDeveloper developer = factory.getDeveloper(operate);result += developer.work() +"\n";result += developer.skill() +"\n";//通过工厂获得公司产品人员IProductor productor = factory.getProductor(operate);result += productor.work() +"\n";result += productor.skill() +"\n";return result;
java工厂模式实例(设计模式)相关推荐
- java设计模式中不属于创建型模式_23种设计模式第二篇:java工厂模式定义:工厂模式是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式...
23种设计模式第二篇:java工厂模式 定义: 工厂模式是 Java 中最常用的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 工厂模式主要是为创建对象提供过渡接口, ...
- java工厂模式 uml_深入浅出设计模式-简单工厂模式
模式定义 简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一.简单工厂模式定义了一个创建对象的类,由这个类来封装实例化 ...
- java工厂模式和抽象工厂_Java中的抽象工厂设计模式
java工厂模式和抽象工厂 Welcome to Abstract Factory Design Pattern in java example. Abstract Factory design pa ...
- java 工厂模式详解_java 工厂模式的实例详解
java 工厂模式的实例详解 工厂方法中的"工厂"和我们平常理解的一样:用于生产产品. 而客户是要和产品打交道,所以工厂方法模式的意义在于把客户和产品分开,达到解耦和更灵活的目的. ...
- 设计模式之抽象工厂模式实例(c++)
抽象工厂模式实例之电器工厂: 电器工厂类图: 此节也用到了C++反射注册机制,可以参考上篇内容,是一样的. 抽象工厂和工厂方法.简单工厂是有关系的.当抽象工厂中的每一个具体工厂类只生产一个产品对象的时 ...
- java工厂模式式代码_简单工厂模式及其简单Java案例代码实现
说明:本文是<大话设计模式>的学习记录及结合网上相关信息编写,原书代码例子采用C#编写,本文采用Java稍加改写.若有不当,欢迎指正,共同进步.java 1.简单工厂模式概述:设计模式 简 ...
- JAVA -- 工厂模式之 抽象工厂模式
定义: 在spring和其他的框架中,工厂模式被大量使用,实际上工厂模式就是帮助我们实例化对象的设计模式,因为在实际的项目中,实例化对象的同时,可能对象中有大量的初始化工作,如果每次项目有个地方用到这 ...
- 传统方式解决披萨订购(工厂模式实例)
传统方式解决披萨订购(工厂模式实例) 包1: 披萨 package com.atguigu.design.factory;//将pizza做成抽象类public abstract class Pizz ...
- Java工厂模式(随笔)
目录 前言 一.三大工厂模式以及特殊工厂模式介绍 1.简单工厂模式简介(Simple Factory Pattern) 2.工厂模式简介 (Factory Pattern) 3.抽象工厂模式简介 ...
最新文章
- 一、Tableau基础
- 2013年10月1日C#随机数
- ​关于深度学习、NLP和计算机视觉的30个顶级Python库
- DataArtisans战略联手阿里云 Apache Flink服务能力云化
- 首届渣打科营编程马拉松赛初赛圆满结束
- windowbuilder怎么加图片_一键制作音乐图片,这效果太惊艳了!微信这个功能简直是“宝藏”...
- 不清楚SBUS,这份SBUS协议详解请收藏
- python123第九周测验答案2020_脑筋急转弯:什么牛是最好骗的?这答案能笑死人...
- 小知识--Windows语音效果
- 微信授权+JS-SDK
- 关于fftshift引发的问题与思考
- java字节流字符流复制文件大小不一致及乱码
- 假华为手机窝点被查!画面不忍直视
- 2022-2027年中国环保领域集团级sis系统行业市场调研及未来发展趋势预测报告
- 神秘的古文明 ———— 埃及文化
- 重装系统ie无法解析服务器名称,教你解决ie浏览器打不开的方法
- gitlab安装教程、gitlab官网、英文文档
- POJ,3713 Transferring Sylla
- 国内代码托管平台gitee的使用
- 戴尔服务器的安装维护和调试,服务器的安装与维护技巧——数据湾