当前位置:网站首页>工厂模式
工厂模式
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解耦
- 工厂方法,为了保存旧代码,扩展功能时不对代码进行修改,同一等级的不同对象有自己的工厂,每个工厂只创建自己的对象,这样在扩展的时候只用创建一个工厂类和一个对象类,不用修改代码
- 抽象工厂,对具有相同特点的同一对象族进行抽象,得到的抽象工厂可以创建同一个对象族不同等级的对象,一个工厂类对应一个对象族,一个方法对应一个对象等级
边栏推荐
- Redis系列:高可用之Sentinel(哨兵模式)
- what is a .pro file in qt
- The strongest JVM in the whole network is coming!(Extreme Collector's Edition)
- CesiumJS 2022^ 源码解读[0] - 文章目录与源码工程结构
- 外包干了五年,废了...
- Worthington Dissociation Enzymes: Trypsin and Frequently Asked Questions
- 利用热点事件来创作软文的3大技巧?自媒体人必看
- 自媒体短视频标题怎么写?3个爆款标题,让你的视频收获更多流量
- Go language serialization and deserialization and how to change the uppercase of the json key value to lowercase if the json after serialization is empty
- 557. 反转字符串中的单词 III
猜你喜欢

How do we-media people create explosive articles?These 3 types of articles are most likely to explode

vim相关介绍(三)

EA & UML Sun Gong Yip - Multitasking Programming Super Introductory - (7) About mutex, you must know

月薪15k的阿里测试岗,面试原来这么简单

Worthington Dissociation Enzymes: Collagenase and Four Basic Profiles

Elephant Swap: Provide arbitrage space in the crypto market with ePLATO

KDE Frameworks 5.20.0:Plasma迎来诸多改进

At the age of 29, I was fired from a functional test. Can't find a job after 2 months of interviews?

Since the media how to write a short video title?Three hot style title, let your video gain more traffic

Worthington解离酶:中性蛋白酶(分散酶)详情解析
随机推荐
单片机开发之拓展并行I/O口
月薪15k的阿里测试岗,面试原来这么简单
Douyin short video traffic acquisition strategy, mastering these will definitely be a hit
从面试官角度分析:面试功能测试工程师主要考察哪些能力?
UE4 makes crosshair + recoil
【分层强化学习】survey
what is a .pro file in qt
Worthington's tried and tested cell isolation system protocols
旋转数组的最小数字
Mysql internal and external connections
Chinese semantic matching
UE4 制作十字准心+后坐力
软件测试拿8k以上有多简单,掌握这些随随便便拿8k以上...
Worthington解离酶:中性蛋白酶(分散酶)详情解析
cp强制覆盖与不覆盖拷贝方法
Comprehensive Practice - Three-Mison Chess Mini Game
ZLMediaKit源码分析 - WebRtc连接迁移
2022年企业直播行业发展洞察
WeChat developer tools set the tab size to 2
更换可执行文件glibc版本的某一次挣扎