设计模式-创建型模式1:单例模式+工厂模式

单例模式

  • 单例模式是创建型设计模式
  • 核心思想:一个类只有一个实例,并提供一个全局访问点来访问这个实例

单例设计模式的实现

  • 懒汉式:只有请求实例时才完成创建,需要使用了再创建;
  • 饿汉式:在类加载时,已经完成实例创建;

适用场景

  1. 资源共享;
  2. 只有一个实例;
  3. 懒加载:对象本身比较消耗资源,在整个程序中不一定会使用;

懒汉模式多线程安全

import threading
import sys
 
class shoppingcartmanager:
    __instance = None
    __lock = threading.Lock()
     
    def __init__(self):
        self.cart = {}

   ## 判断是否是唯一实例
    @classmethod
    def getInstance(cls):
        if cls.__instance is None:
            with cls.__lock:
                if cls.__instance is None:
                    cls.__instance = shoppingcartmanager()
        return cls.__instance

def main():
    cart_ins = shoppingcartmanager.getInstance()

饿汉模式

import sys
 
class ShoppingCartManager:
     
    __instance = None  # 静态变量,保存类的唯一实例
    ###懒汉模式 判断永远是唯一的instance
    def __new__(cls, *args, **kwargs):
        if cls.__instance is None:
            cls.__instance = super(ShoppingCartManager, cls).__new__(cls)
        return cls.__instance
 
    def __init__(self):
        self.cart = {}  # 初始化购物车的商品字典
     
    @classmethod
    def get_instance(cls):
        return cls.__instance
     
    def add_to_cart(self, key, value):
        self.cart[key] = self.cart.get(key, 0) + value
     
    def show_cart(self):
        for key, value in self.cart.items():
            print(f"{key} {value}")
 
# 在类加载时立即创建实例
ShoppingCartManager()
 
def main():
    cart_ins = ShoppingCartManager.get_instance()
    while True:
        line = sys.stdin.readline()
        if not line.strip():  # 结束条件
            break
        good_list = line.split()
        cart_ins.add_to_cart(good_list[0], int(good_list[1]))
    cart_ins.show_cart()
 
if __name__ == '__main__':
    main()

工厂方法模式

题目链接:https://kamacoder.com/problempage.php?pid=1076

  • 简单工厂模式
    • 创建型设计模式:将产品的创建过程封装在一个工厂类中,将创建对象的流程集中在工程类中
      • 主要角色:工厂类:创建产品、抽象产品:产品的各类接口、具体产品:实现抽象产品接口或继承抽象产品类;
  • 工厂方法模式
    • 抽象工厂:一个接口,包含一个抽象的工厂方法(用于创建产品对象);
    • 具体工厂:定义抽象接口,创建具体产品;
    • 抽象产品:定义产品接口;
    • 具体产品:实现抽象产品的接口,是工厂创建对象
  • 应用场景
    工厂方法模式使得每个工厂类的职责单一,每个工厂只负责创建一种产品,当创建对象涉及一系列复杂的初始化逻辑,而这些逻辑在不同的子类中可能有所不同时,可以使用工厂方法模式将这些初始化逻辑封装在子类的工厂中。在现有的工具、库中,工厂方法模式也有广泛的应用,比如:
    • Spring 框架中的 Bean 工厂:通过配置文件或注解,Spring 可以根据配置信息动态地创建和管理对象。
    • JDBC 中的 Connection 工厂:在 Java 数据库连接中,DriverManager 使用工厂方法模式来创建数据库连接。不同的数据库驱动(如 MySQL、PostgreSQL 等)都有对应的工厂来创建连接。
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

// 抽象积木接口
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 createBlock();
}

// 具体圆形积木工厂实现
class CircleBlockFactory implements BlockFactory {
    @Override
    public Block createBlock() {
        return new CircleBlock();
    }
}

// 具体方形积木工厂实现
class SquareBlockFactory implements BlockFactory {
    @Override
    public Block createBlock() {
        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.createBlock();
            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);
            }
        }
    }
}

抽象工厂

题目链接:https://kamacoder.com/problempage.php?pid=1077

在工厂方法模式中,每个具体工厂只负责创建单一的产品。但是如果有多类产品呢,比如说“手机”,一个品牌的手机有高端机、中低端机之分,这些具体的产品都需要建立一个单独的工厂类,但是它们都是相互关联的,都共同属于同一个品牌,这就可以使用到【抽象工厂模式】。

创建“多类”对象了,在工厂方法模式中,每个具体工厂只负责创建单一的产品。但是如果有多类产品呢,比如说“手机”,一个品牌的手机有高端机、中低端机之分,这些具体的产品都需要建立一个单独的工厂类,但是它们都是相互关联的,都共同属于同一个品牌,这就可以使用到【抽象工厂模式】。

  • 基本结构
    • 抽象产品接口
    • 具体产品类
    • 抽象工厂接口
    • 具体工厂类
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) {
    /* code */
        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();
        }
        
    }
}
posted @ 2024-08-14 15:08  哆啦**  阅读(14)  评论(0编辑  收藏  举报