Java设计模式--工厂模式

news2024/9/22 15:25:52

目录

1.简单工厂模式

1.1类图

1.2 代码示例

2.工厂方法模式

2.1 类图

2.2 代码示例

3.抽象工厂模式

3.1 类图

3.2 代码示例

实际应用:

 总结:


1.简单工厂模式

        定义了一个创建对象的类,由这个类来封装实力化对象的行为。

1.1类图

 

1.2 代码示例

pizza基类

package org.example.factory.simplefactory.pizzastore.pizza;

import lombok.Data;

@Data
public abstract class Pizza {

    String name = "";

    // 准备pizza的原材料
    public abstract void prepare();

    public void bake(){
        System.out.println(name +" 烘培 ");
    }

    public void cut(){
        System.out.println(name +" 裁剪 ");
    }

    public void box(){
        System.out.println(name +" 开始打包... ");
    }
}

奶酪披萨

package org.example.factory.simplefactory.pizzastore.pizza;

public class ChessPizza extends Pizza {
    @Override
    public void prepare() {
        System.out.println(" 奶酪披萨 准材料 ");
    }
}

希腊披萨

package org.example.factory.simplefactory.pizzastore.pizza;

public class GreekPizza extends Pizza {
    @Override
    public void prepare() {
        System.out.println(" 希腊披萨 准备材料");
    }
}

简单工厂类

package org.example.factory.simplefactory.pizzastore.order;

import org.example.factory.simplefactory.pizzastore.pizza.ChessPizza;
import org.example.factory.simplefactory.pizzastore.pizza.GreekPizza;
import org.example.factory.simplefactory.pizzastore.pizza.Pizza;

public class SimpleFactory {

    public Pizza createPizza(String type){
        Pizza pizza;
        do{
            if (type.equals("chess")) {
                pizza = new ChessPizza();
                pizza.setName("奶酪");
            } else if (type.equals("greek")){
                pizza = new GreekPizza();
                pizza.setName("希腊");
            } else {
                break;
            }
            System.out.println(" 披萨制作完成! ");

            return pizza;
        }while (true);
        return null;
    }
}

订单类

package org.example.factory.simplefactory.pizzastore.order;

import org.example.factory.simplefactory.pizzastore.pizza.Pizza;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class OrderPizza {

    SimpleFactory simpleFactory;

    Pizza pizza;

    public OrderPizza(SimpleFactory simpleFactory){
        setSimpleFactory(simpleFactory);
    }

    public void setSimpleFactory(SimpleFactory simpleFactory){
        String type = "";
        do {
            this.simpleFactory = simpleFactory;
            type = getType();
            pizza = this.simpleFactory.createPizza(type);
            if (pizza != null) {
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            } else {
                System.out.println(" 订购失败,没有这种类型的披萨~ ");
                break;
            }
        } while (true);
    }

    public String getType(){
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            System.out.println(" 输入披萨的种类: ");
            return reader.readLine();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

披萨商店主程序入口

package org.example.factory.simplefactory.pizzastore.order;

public class PizzaStore {
    public static void main(String[] args) {
        new OrderPizza(new SimpleFactory());

        System.out.println(" 订单完成! ");
    }
}

2.工厂方法模式

        定义了一个创建对象的抽象方法,由子类决定要实例化的类,工厂方法模式将对象的实例化推迟到子类中去实现。

2.1 类图

 

2.2 代码示例

        与简单工厂模式相比,在原有的披萨种类基础上添加了地区区分,在代码上修改了订单类,添加了两个订单子类。

订单类

package org.example.factory.factorymethod.pizzastore.order;


import org.example.factory.factorymethod.pizzastore.pizza.Pizza;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class OrderPizza {

    Pizza pizza;

    public OrderPizza(){
        setSimpleFactory();
    }

    public void setSimpleFactory(){
        String loc = "";
        String type = "";
        do {
            loc = getType("地区");
            if (loc.equals("bj")) {
                type = getType("披萨种类");
                pizza = BJOrderPizza.createPizza(type);
            } else if (loc.equals("ld")) {
                type = getType("披萨种类");
                pizza = LDOrderPizza.createPizza(type);
            } else {
                System.out.println(" 订购失败,没有该地区~ ");
                break;
            }
            if (pizza != null) {
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            } else {
                System.out.println(" 订购失败,没有这种类型的披萨~ ");
                break;
            }
        } while (true);
    }

    public String getType(String str){
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            System.out.println(" 输入"+str+": ");
            return reader.readLine();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

BJ订单类

package org.example.factory.factorymethod.pizzastore.order;

import org.example.factory.factorymethod.pizzastore.pizza.BJApplePizza;
import org.example.factory.factorymethod.pizzastore.pizza.BJCheesePizza;
import org.example.factory.factorymethod.pizzastore.pizza.Pizza;

public class BJOrderPizza {

    public static Pizza createPizza(String type){

        Pizza pizza = null;

        if (type.equals("apple")) {
            pizza = new BJApplePizza();
            pizza.setName("北京苹果披萨");
        } else if (type.equals("cheese")) {
            pizza = new BJCheesePizza();
            pizza.setName("北京奶酪披萨");
        }
        return pizza;
    }

}

LD订单类

package org.example.factory.factorymethod.pizzastore.order;

import org.example.factory.factorymethod.pizzastore.pizza.BJApplePizza;
import org.example.factory.factorymethod.pizzastore.pizza.BJCheesePizza;
import org.example.factory.factorymethod.pizzastore.pizza.Pizza;

public class LDOrderPizza {
    public static org.example.factory.factorymethod.pizzastore.pizza.Pizza createPizza(String type){

        Pizza pizza = null;

        if (type.equals("apple")) {
            pizza = new BJApplePizza();
            pizza.setName("伦敦苹果披萨");
        } else if (type.equals("cheese")) {
            pizza = new BJCheesePizza();
            pizza.setName("伦敦奶酪披萨");
        }
        return pizza;
    }
}

3.抽象工厂模式

        定义一个interface用于创建相关或有依赖关系的对象簇,而无需指明具体的类;将简单工厂模式和工厂方法模式整合,将工厂抽象出两层,一个是抽象工厂,一个是具体的实现的工厂子类。

3.1 类图

3.2 代码示例

新增抽象工厂类

package org.example.factory.absfactory.pizzastore.order;

import org.example.factory.absfactory.pizzastore.pizza.Pizza;

//抽象工厂类
public interface AbsFactory {
    public Pizza createPizza(String type);
}

抽象工厂类的具体实现类

BJ工厂类用于创建对象并返回

package org.example.factory.absfactory.pizzastore.order;

import org.example.factory.absfactory.pizzastore.pizza.BJApplePizza;
import org.example.factory.absfactory.pizzastore.pizza.BJCheesePizza;
import org.example.factory.absfactory.pizzastore.pizza.Pizza;

public class BJFactory implements AbsFactory{

    @Override
    public Pizza createPizza(String type) {
        System.out.println(" 使用的是抽象工厂模式~ ");
        Pizza pizza = null;
        if (type.equals("apple")) {
            pizza = new BJApplePizza();
        } else if (type.equals("cheese")) {
            pizza = new BJCheesePizza();
        }
        return pizza;
    }

}

LD工厂类

package org.example.factory.absfactory.pizzastore.order;

import org.example.factory.absfactory.pizzastore.pizza.LDApplePizza;
import org.example.factory.absfactory.pizzastore.pizza.LDCheesePizza;
import org.example.factory.absfactory.pizzastore.pizza.Pizza;

public class LDFactory implements AbsFactory{

    @Override
    public Pizza createPizza(String type) {
        System.out.println(" 使用的是抽象工厂模式~ ");
        Pizza pizza = null;
        if (type.equals("apple")) {
            pizza = new LDApplePizza();
        } else if (type.equals("cheese")) {
            pizza = new LDCheesePizza() ;
        }
        return pizza;
    }

}

订单类

package org.example.factory.absfactory.pizzastore.order;

import org.example.factory.absfactory.pizzastore.pizza.Pizza;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class OrderPizza {

    AbsFactory factory;

    public OrderPizza(AbsFactory factory){
        setFactory(factory);
    }

    private void setFactory(AbsFactory factory){
        Pizza pizza = null;
        String type = "";
        this.factory = factory;
        do {
            type = getType("披萨种类");
            pizza = factory.createPizza(type);
            if (pizza != null) {
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            } else {
                System.out.println(" 订购失败 ");
                break;
            }
        } while (true);
    }

    private String getType(String str){
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            System.out.println(" 输入"+str+": ");
            return reader.readLine();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

实际应用:

        在JDK的源码java.util.Calendar中使用到了简单工厂模式:

 总结:

        设计模式的依赖抽象原则:

        创建对象实例时,不要之间new类,而是把这个动作交给工厂的方法并返回;

        不要让类继承具体类,而是继承抽象类或实现接口;

        不要覆盖基类中已经实现的方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/196310.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《三体》中罗辑所说的定位行星的位置,是怎样实现的?

最近流浪地球2,三体电视剧火得一塌糊涂,《三体》中罗辑用咒语标记了三体星系位置,利用黑暗森林理论与三体人对峙长达两百年,那么这种定位技术在现实中是否存在呢?咒语标记三体星系位置这件事,听起来很玄乎但…

vite兼容chrome48的方法

chrome48不支持async await语法,但有些桌面客户端的内嵌浏览器就是chrome48,如下操作即可兼容 当前环境:2023-2-3使用npm create vitelatest创建 开始兼容操作 安装vite推荐的 vitejs/plugin-legacy 文档官网 https://github.com/vitejs/vite/tree/m…

【JavaEE】HTTP的方法、报头、状态码

✨哈喽,进来的小伙伴们,你们好耶!✨ 🛰️🛰️系列专栏:【JavaEE】 ✈️✈️本篇内容:http请求的方法、报头;状态码! 🚀🚀代码存放仓库gitee:JavaEE代码&#…

学习QCustomPlot【4】库官方examples之plots解读

文章目录一、前言二、案例解说0:Quadratic Demo【二次曲线demo】1、Simple Demo【简单demo】2、Sinc Scatter Demo【Sinc函数散点demo】3、Scatter Style Demo【散点样式demo】4、Line Style Demo【线型demo】5、Scatter Pixmap Demo【图标散点demo】6、Date Demo【…

RANSAC的实现与应用

一、前言RANSAC(Random Sample Consensus)算法并不陌生,在上一篇博客中(基于SIFT的图像Matlab拼接教程)也提到过,之前代码中也多次用过,其在直(曲)线拟合、特征匹配、过滤外点(Outlier)等领域有着重要的应用。RANSAC出…

线性代数之线性基

在谈论线性基之前,先介绍什么是基向量. 根据高中数学,一个二维直角平面坐标系中的所有向量都可以只用(0, 1)和(1, 0)合成.那么(0, 1)和(1, 0)就是基向量,所有基向量能合成的所有向量被称为基向量的张成空间. 在二维空间中,有没有其他的向量能作为基向量呢?答案是肯定的. 上图…

Oracle事務簡述

簡述本文主要介紹內容有事務的隔離級別,oracle支持的事務隔離級別,事務的提交與回滾,保存點內容事務的ACID特征介紹事務繞不過事務的ACID四個特征,這裡簡單回顧以下原子性(Atomicity)事務的執行要麼全部成功…

广义霍夫变换和模板匹配的不同

简述说到霍夫变换,做图像的知道经典霍夫变换最常用于检测规则曲线,如直线、圆、椭圆等。而广义霍夫变换是为了检出那些无法写出解析式的不规则形状,虽然在深度学习大行其道的时代,霍夫变换也还是有很多应用场景,另外广…

2023年黑马Java入门到精通教程--面向对象

推荐教程:java零基础入门到精通 面向对象编程的例子 设计类,创建对象并使用 1. 类和对象是什么? 类:是共同特征的描述(设计图);对象:是真实存在的具体实例。 2. 如何设计类? 3. 如何创建对象…

CISP-PTE-Windows2003教程

为方便后续操作,建议和kali在同一网段。 获取到靶机IP后,扫描端口,1433是sqlserver的 测出用户名admin,但是密码爆破失败 扫描目录发现配置文件 配置文件中找到数据库的用户名和密码 使用Microsoft SQL Server Studio连接&#x…

MySQL从入门到精通(第0篇):全程有动画演示,适合入门学习

B站地址 文章目录一、MySQL的系统框架1. 连接池1.1 连接模块1.2 连接池2. SQL接口、SQL解析器、SQL优化器3. 存储引擎二、MySQL数据写入原理三、MySQL存储结构1. 使用InnoDB创建表2. 详述ibd文件中的存储结构2.1 页的数据连续存储2.2 行的结构2.3 区的结构2.4 组的结构2.5 段的…

剑指 Offer 33. 二叉搜索树的后序遍历序列

题目 输入一个整数数组&#xff0c;判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true&#xff0c;否则返回 false。假设输入的数组的任意两个数字都互不相同。 思路 二叉搜索树的特点是&#xff1a;左子树的值 < 根节点 < 右子树的值后序遍历的顺序是…

【逐步剖C】第三章-数组

一、一维数组 1. 一维数组的定义与使用 &#xff08;1&#xff09;数组的简单概念&#xff1a;一组具有相同类型的元素的集合 &#xff08;2&#xff09;数组的创建&#xff1a; 格式&#xff1a;类型名数组名[数组大小] 需要注意的是&#xff1a;对多数情况而言&#xff0c;…

# Vue中的Mixin混入

Vue中的Mixin混入 将组件的公共逻辑或者配置提取出来&#xff0c;哪个组件需要用到时&#xff0c;直接将提取的这部分混入到组件内部即可。这样既可以减少代码冗余度&#xff0c;也可以让后期维护起来更加容易。 1. 什么是Mixin&#xff1f; 混入 (mixin) 混入 (mixin) 将组…

数据库分类

关系型与非关系型 关系数据库 MySQL、MariaDB&#xff08;MySQL的代替品&#xff09;、 Percona Server&#xff08;MySQL的代替品&#xff09;、PostgreSQL、 Microsoft Access、Google Fusion Tables、SQLite、DB2、FileMaker、Oracle、SQL Server、INFORMIX、Sybase、dBASE…

阿里云中间件2024届校园招聘

【团队介绍】 阿里云云原生中间件团队负责分布式软件基础设施&#xff0c;为阿里云上万家企业提供如微服务引擎、服务网格、消息服务、分布式事务等分布式基础服务&#xff0c;加速企业上云的进程和创新速度。同时&#xff0c;云原生中间件团队也服务着阿里集团众多核心业务和…

智能指针(三)—— shared_ptr 循环引用问题

shared_ptr 作为智能指针&#xff0c;可以满足大多数场景&#xff0c;对于一些特殊情况&#xff0c;可能会引发循环引用问题。 目录 1、循环引用案例分析 (1) 案例介绍 (2) 原因分析 2、weak_ptr 解决循环引用 1、循环引用案例分析 (1) 案例介绍 我们通过实际案例来了解…

网络编程 1 相关基础概念 及 请求、响应类 定义

目录 一、HTTP基本概念 1、HTTP是什么 2、HTTP客户端是什么 3、HTTP消息结构 4、服务器响应信息 二、相关概念 1、网址 URL 2、IP地址 3、域名 4、域名与IP关系 5、域名解析 6、DNS 三、设计请求、响应类基本数据结构 1、请求类定义 2、响应类定义 一、HTTP基本概…

AD引脚交换

19年写过一篇AD交换引脚的文章&#xff0c;原文请查阅AD18调PIN方法及注意事项&#xff0c;该方法是手动更改焊盘的网络&#xff0c;如果是对于少量的或者零散的引脚交换还好&#xff0c;但遇到像FPGA、CPLD或者端子这种大量引脚需要调PIN的情况还是一个一个手动更改就很费时了…

java 微服务 RabbitMQ高级 消息可靠性问题 死信交换机 延迟队列 惰性队列

消息队列在使用过程中&#xff0c;面临着很多实际问题需要思考&#xff1a; 1.消息可靠性问题&#xff08;面试很会问&#xff09; 针对这些问题&#xff0c;RabbitMQ分别给出了解决方案&#xff1a; 生产者确认机制 mq持久化 消费者确认机制 失败重试机制 下面我们就通过案…