设计模式 Day1| ●创建型模式(1.单例模式、2.工厂方法模式、3.抽象工厂模式、4.建造者模式(也叫生成器模式)、5.原型模式)

day 1-1 1.创建型模式 - ☆☆☆单例模式 - 小明的购物车

题目链接设计模式

什么是单例模式

一个类只有一个实例,并且提供一个全局访问点来访问这个实例
实现:
在这里插入图片描述

为什么要使用单例模式

  • 全局控制
  • 节约资源
  • 懒加载

单例设计模式的基本要求

  • 私有构造函数:防止外部代码直接创建类的实例
  • 私有的静态实例变量:保存该类的唯一实例
  • 公有的静态方法:通过公有的静态方法来获取类的实例
    在这里插入图片描述

单例设计模式的实现

  1. 饿汉式:实例在类加载的时候就被创建,实现相对简单,但是实例有可能没有使用而造成资源浪费
public class Singleton {
    private static final Singleton instance = new Singleton();
    
    private Singleton() {
        // 私有构造方法,防止外部实例化
    }
    
    public static Singleton getInstance() {
        return instance;
    }
}
  1. 懒汉式:第一次使用时才创建,多线程情况下多个线程同时调用getInstance()方法,导致多个实例被创建,存在线程安全问题
public class Singleton {
    private static Singleton instance;
    
    private Singleton() {
        // 私有构造方法,防止外部实例化
    }
    // 使用了同步关键字来确保线程安全, 可能会影响性能
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
  1. 在懒汉式的基础上使用双重检查锁来提高性能
public class Singleton {
    private static volatile Singleton instance;
    
    private Singleton() {
        // 私有构造方法,防止外部实例化
    }
    
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

什么时候使用单例模式

结合单例设计模式的优点来看:

  1. 资源共享
    a. 全局的配置管理器
    b. 数据库连接池
  2. 只有一个实例
    a. 缓存实例
    b. 线程池
  3. 懒加载
    a.对象创建比较消耗资源,而且可能程序中不一定使用的情况
    b.Java的Runntime
    c.Spring框架的应用上下文ApplicationContext

代码实现

  • 饿汉式
// 饿汉式
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        ShoppingCartManger cart = ShoppingCartManger.getInstance();
        Scanner scanner = new Scanner(System.in);
        
        while(scanner.hasNext()){
            String itemName = scanner.next();
            int quantity = scanner.nextInt();
            // 获取购物车实例并添加商品
            cart.addCart(itemName, quantity);
        }
        // 输出购物车内容
        cart.viewCart();
    }
}
class ShoppingCartManger{
    // 饿汉式模式实现单例
    private static final ShoppingCartManger instance = new ShoppingCartManger();
    // 购物车存储商品和数量的映射
    private Map<String, Integer> cart;
    // 私有化构造函数
    private ShoppingCartManger(){
        cart = new LinkedHashMap<>();
    }
    // 获取购物车实例
    public static ShoppingCartManger getInstance(){
        return instance;
    }
    // 添加商品到购物车
    public void addCart(String itemName, int quantity){
        cart.put(itemName, cart.getOrDefault(itemName, 0) + quantity);// value值是在原有的基础上累加
    }
    // 查看购物车
    public void viewCart(){
        for(Map.Entry<String, Integer> entry : cart.entrySet()){
            System.out.println(entry.getKey()+" "+entry.getValue());
        }
    }
    
}
  • 懒汉式
// 懒汉式
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        ShoppingCartManger cart = ShoppingCartManger.getInstance();
        Scanner scanner = new Scanner(System.in);
        
        while(scanner.hasNext()){
            String itemName = scanner.next();
            int quantity = scanner.nextInt();
            // 获取购物车实例并添加商品
            cart.addCart(itemName, quantity);
        }
        // 输出购物车内容
        cart.viewCart();
    }
}
class ShoppingCartManger{
    // 饿汉式模式实现单例
    private static ShoppingCartManger instance; // 修改一
    // 购物车存储商品和数量的映射
    private Map<String, Integer> cart;
    // 私有化构造函数
    private ShoppingCartManger(){
        cart = new LinkedHashMap<>();
    }
    // 获取购物车实例
    public static ShoppingCartManger getInstance(){ // 修改二 
        if(instance == null){
            return instance = new  ShoppingCartManger();
        }else{
            return instance;
        }
        
    }
    // 添加商品到购物车
    public void addCart(String itemName, int quantity){
        cart.put(itemName, cart.getOrDefault(itemName, 0) + quantity);// value值是在原有的基础上累加
    }
    // 查看购物车
    public void viewCart(){
        for(Map.Entry<String, Integer> entry : cart.entrySet()){
            System.out.println(entry.getKey()+" "+entry.getValue());
        }
    }
    
}
  • 懒汉 + 双重锁检查
// 懒汉 + 双重锁检查
// 懒汉式 + 双重锁检查 + 格式检查加强
import java.util.Scanner;
import java.util.ArrayList;
class ShoppingCartManger{
    // 购物车管理器的单例变量,使用volatile关键字确保线程安全
    private static volatile ShoppingCartManger instance;
    //
    private static ArrayList<String> productNames = new ArrayList<>();
    // 
    private static ArrayList<Integer> productQuantities = new ArrayList<>();
    // 
    private ShoppingCartManger(){
        
    }
    // 获取购物车单例实例的方法,确保线程安全 双重锁检查
    public static ShoppingCartManger getInstance(){
        if(instance == null){
            synchronized(ShoppingCartManger.class){
                instance = new ShoppingCartManger();
            }
        }
        return instance;
    }
    // 添加商品到购物车
    public void add(String itemName, int quantity){
        productNames.add(itemName);
        productQuantities.add(quantity);
        System.out.println(itemName + " " + quantity);
    }
}
public class Main{
    public static void main(String[] args){
        ShoppingCartManger cart = ShoppingCartManger.getInstance();
        Scanner scanner = new Scanner(System.in);
        
        String inputLine;
        // 循环读取用户输入,直到用户输入"exit"
        while(scanner.hasNextLine()){
            inputLine = scanner.nextLine();
            if("exit".equalsIgnoreCase(inputLine)){
                break;
            }
            String[] parts = inputLine.split(" ");
            if(parts.length == 2){
                String itemName = parts[0];
                int quantity;
                try{
                    quantity = Integer.parseInt(parts[1]);
                    cart.add(itemName, quantity);
                }catch (NumberFormatException e){
                    System.out.println("转换失败,请重新输入");
                }
            }else{
                System.out.println("输入格式不争取,请重新输入");
            }
        }
        scanner.close();
    }
}

day 1-2 2.创建型模式 - ☆工厂方法模式 - 积木工厂

简单工厂模式

是一种创建型设计模式,但不属于23种设计模式之一,是一种编程习惯
将产品的创建过程封装在一个工厂类中,主要角色包括如下:

  • 抽象产品:描述产品的通用行为
  • 具体产品:实现抽象产品接口或者继承抽象产品类
  • 工厂类:负责创建产品

优点:简化了客户端操作,客户端可以调用工厂方法来获取具体产品
缺点:不够灵活,如果需要添加新的产品,就需要修改工厂类的代码。

什么是工厂方法模式

引入抽象工厂和具体工厂,每个工厂只负责创建一个具体产品
工厂方法模式包括的角色如下:

  • 抽象工厂:一个接口,包含一个抽象的工厂方法(用于创建产品)
  • 具体工厂:实现抽象工厂接口,创建具体的产品
  • 抽象产品:定义产品的接口
  • 具体产品:实现抽象产品的接口,是工厂创建的对象

基本实现

TODO 图 + 代码

应用场景

特点:工厂方法模式每个工厂职责单一,每个工厂只负责一种产品
应用:

  • Spring框架中的Bean工厂
  • JDBC的Connection工厂

代码实现

import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;
// 抽象积木接口
interface Block{
    void produce();
}
// 具体圆形积木实现
class CircleBlock implements Block{
    @Override
    public void produce(){
        System.out.println("Circle Block");
    }
}
// 具体方形积木实现
class SquareBlock implements Block{
    @Override
    public void produce(){
        System.out.println("Square Block");
    }
}
// 抽象积木工厂接口
interface BlockFactory{
    Block creatBlock();
}
// 具体圆形积木工厂实现
class CircleBlockFactory implements BlockFactory{
    @Override
    public Block creatBlock(){
        return new CircleBlock();
    }
}
// 具体方形积木工厂实现
class SquareBlockFactory implements BlockFactory{
    @Override
    public Block creatBlock(){
        return new SquareBlock();
    }
}
// 积木工厂系统
class BlockFactorySystem{
    private List<Block> blocks = new ArrayList<>();
    public void produceBlocks(BlockFactory factory, int quantity){
        for(int i = 0; i < quantity; i++){
            Block block = factory.creatBlock();
            blocks.add(block);
            block.produce();
        }
    }
    public List<Block> getBlocks(){
        return blocks;
    }
}
public class Main{
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        // 创建积木工厂系统
        BlockFactorySystem factorySystem = new BlockFactorySystem();
        // 获取生成次数
        int productionCount = scanner.nextInt();
        scanner.nextLine();// 换行
        
        for(int i = 0; i < productionCount; i++){
            String[] productionInfo = scanner.nextLine().split(" ");
            String blockType = productionInfo[0];
            int quantity = Integer.parseInt(productionInfo[1]);
            
            if(blockType.equals("Circle")){
                factorySystem.produceBlocks(new CircleBlockFactory(), quantity);
            }else if(blockType.equals("Square")){
                factorySystem.produceBlocks(new SquareBlockFactory(), quantity);
            }
        }
        
    }
}

day 1-3 3.创建型模式 - 抽象工厂模式 - 家具工厂

什么是抽象工厂模式

一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类

具体结构

主要角色包括:

  • 抽象产品接口
  • 具体产品类
  • 抽象工厂接口
  • 具体工厂类
    和工厂方法的角色相同

具体实现

TODO:图+代码

应用场景

扩展性差,使用于一系列相关或相互依赖的产品被一起创建的情况

  • 创建与不同数据库的连接对象

简单工厂、工厂方法、抽象工厂的区别

简单工厂模式:一个工厂方法创建所有的具体产品
工厂方法模式:一个工厂创建一个具体的产品
抽象工厂模式:一个工厂方法可以创建一类具体产品

本题代码实现

import java.util.Scanner;
// 抽象椅子接口
interface Chair{
    void showInfo();
}
// 具体现代椅子实现
class ModernChair implements Chair{
    @Override
    public void showInfo(){
        System.out.println("modern chair");
    }
}
// 具体古典风格椅子实现
class ClassicalChair implements Chair{
    @Override
    public void showInfo(){
        System.out.println("classical chair");
    }
}
// 抽象沙发接口
interface Sofa{
    void displayInfo();
}
// 具体现代风格沙发实现
class ModernSofa implements Sofa{
    @Override
    public void displayInfo(){
        System.out.println("modern sofa");
    }
}
// 具体经典风格沙发实现
class ClassicalSofa implements Sofa{
    @Override
    public void displayInfo(){
        System.out.println("classical sofa");
    }
}
// 抽象家具工厂接口
interface FurnitureFactory{
    Chair createChair();
    Sofa createSofa();
}
// 具体现代风格家具工厂实现
class ModernFurnitureFactory implements FurnitureFactory{
    @Override
    public Chair createChair(){
        return new ModernChair();
    }
    @Override
    public Sofa createSofa(){
        return new ModernSofa();
    }
}
// 具体经典风格家具工厂实现
class ClassicalFurnitureFactory implements FurnitureFactory{
    @Override
    public Chair createChair(){
        return new ClassicalChair();
    }
    @Override
    public Sofa createSofa(){
        return new ClassicalSofa();
    }
}
public class Main{
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        // 读取订单数量
        int N = scanner.nextInt();
        // 处理订单
        for(int i = 0; i < N; i++){
            // 读取家具类型
            String furnitureType = scanner.next();
            // 创建相应风格的家具装饰品工厂
            FurnitureFactory  factory = null;
            if(furnitureType.equals("modern")){
                factory = new ModernFurnitureFactory();
            }else if(furnitureType.equals("classical")){
                factory = new ClassicalFurnitureFactory();
            }
            // 根据工厂生产椅子和沙发
            Chair chair = factory.createChair();
            Sofa sofa = factory.createSofa();
            // 输出家具信息
            chair.showInfo();
            sofa.displayInfo();
        }
    }
}

day 1-4 4.创建型模式 - ☆建造者模式 - 自行车加工

什么是建造者模式(也称为生成器模式

需要创建很复杂的对象,将对象的构建过程分为多个步骤

基本结构

  • 产品
  • 抽象建造者
  • 具体建造者
  • 指导者

简单实现

TODO 图 + 对应代码

使用场景

优点:

  • 解构
  • 构建过程可以创建不同的表示
    应用:
  • JUnit中的测试构建器TestBuilder

本题代码实现

import java.util.Scanner;
// 自行车产品
class Bike{
    private String frame;
    private String tires;
    public void setFrame(String frame){
        this.frame = frame;
    }
    public void setTires(String tires){
        this.tires = tires;
    }
    @Override
    public String toString(){
        return frame + " " + tires;
    }
}
// 自行车构建者接口
interface BikeBuilder{
    void buildFrame();
    void buildTires();
    Bike getResult();
}
//  山地自行车构建者
class MountainBikeBuilder implements BikeBuilder{
    private Bike bike;
    // 静态方法
    public MountainBikeBuilder(){
        this.bike = new Bike();
    }
    @Override
    public void buildFrame(){
        bike.setFrame("Aluminum Frame");
    }
    @Override
    public void buildTires(){
        bike.setTires("Knobby Tires");
    }
    @Override
    public Bike getResult(){
        return bike;
    }
}
// 公路自行车构建者
class RoadBikeBuilder implements BikeBuilder{
    private Bike bike;
    // 静态方法
    public RoadBikeBuilder (){
        this.bike = new Bike();
    }
    @Override
    public void buildFrame(){
        bike.setFrame("Carbon Frame");
    }
    @Override
    public void buildTires(){
        bike.setTires("Slim Tires");
    }
    @Override
    public Bike getResult(){
        return bike;
    }
}
// 自行车指挥者Director, 负责构建自行车
class BikeDirector{
    public Bike construct(BikeBuilder builder){
        builder.buildFrame();
        builder.buildTires();
        return builder.getResult();
    }
}

public class Main{
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        // 订单数量
        int N = scanner.nextInt();
        // 换行
        scanner.nextLine();
        BikeDirector director = new BikeDirector();
        for(int i = 0; i < N; i++){
            String  bikeType = scanner.nextLine();
            BikeBuilder builder;
            // 根据需求类型创建不同类型的自行车构建者
            if(bikeType.equals("mountain")){
                builder = new MountainBikeBuilder();
            }else { // 不知道这里使用else if(bikeType.equals("road"))为啥不行
                builder = new RoadBikeBuilder();
            }
            // director负责指导生产产品
            Bike bike = director.construct(builder);
            System.out.println(bike);
        }
    }    
}







day 1-5 5.创建型模式 - 原型模式 - 矩形原型

什么是原型模式

基于现有的对象创建新的对象,而不是从头开始创建

为什么使用原型模式

一个对象的创建过程比较复杂,降低对象创建的成本

原型模式的基本结构

  • 抽象原型接口Prototype
  • 具体原型类ConcretePrototype

原型模式的基本实现

TODO: 图 + 代码

什么时候实现原型模式

需要考虑到的问题,对象内部成员包含了引用类型的成员变量,深拷贝比较复杂
实际应用的例子:

  • Java提供的Object类的clone()方法,实现对象的浅拷贝
  • Spring框架的Bean的作用域之一是原型作用域(Prototype Scope)

本题代码实现

import java.util.Scanner;
// 抽象原型类
abstract class Prototype implements Cloneable{
    public abstract Prototype clone();
    public abstract String getDetails();
    // 公用的clone方法
    public Prototype clonePrototype(){
        try{
            return (Prototype)super.clone();
        }catch (CloneNotSupportedException e){
            e.printStackTrace();
            return null;
        }
    }
}
// 具体矩形原型类
class RectanglePrototype extends Prototype{
    private String color;
    private int width;
    private int height;
    // 构造方法
    public RectanglePrototype(String color, int width, int height){
        this.color = color;
        this.width = width;
        this.height = height;
    }
    // 克隆方法
    @Override
    public Prototype clone(){
        return clonePrototype();
    }
    // 获取矩形的详细信息
    @Override
    public String getDetails(){
        return "Color: " + color + ", " + "Width: " + width + ", " + "Height: " + height;
    }
}
// 客户端程序
public class Main{
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        // 属性信息
        String[] input = scanner.nextLine().split(" ");
        String color = input[0];
        int width = Integer.parseInt(input[1]);
        int height = Integer.parseInt(input[2]);
        // 创建原型对象
        RectanglePrototype originalRectangle = new RectanglePrototype(color, width, height);
        int N = scanner.nextInt();
        // 创建指定数量的矩形对象并输出信息
        for(int i = 0; i < N; i++){
            Prototype clonedRectangle =  originalRectangle.clone();
            System.out.println(clonedRectangle.getDetails());
        }
    }
}

总结

  • 耗时:4h10min
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值