首页 > 其他分享 >设计模式

设计模式

时间:2024-04-23 15:12:12浏览次数:21  
标签:void class println protected Override 设计模式 public

设计模式

前言

设计模式是一种通用的思维方式,可以在各个行业和领域中应用,帮助设计师和工程师解决复杂的设计和工程问题,提高系统的质量和效率。

在软件开发过程中,我们要减少重复代码,对修改关闭,对扩展开放,但是切勿提前过度设计。设计模式不是银弹,过度使用设计模式反而会使代码变得复杂和难以理解。

参考基本原则

  1. 单一职责原则(Single Responsibility Principle,SRP):一个类应该只有一个引起变化的原因。换句话说,一个类应该只有一个责任。
  2. 开闭原则(Open-Closed Principle,OCP):软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。即对于已经实现的功能模块,应该在不修改其源代码的情况下进行扩展。
  3. 里氏替换原则(Liskov Substitution Principle,LSP):子类型必须能够替换其基类型而不影响程序的正确性。换句话说,任何基类可以出现的地方,子类一定可以出现。
  4. 依赖倒置原则(Dependency Inversion Principle,DIP):高层模块不应该依赖于低层模块,二者都应该依赖于抽象。抽象不应该依赖于具体实现细节,具体实现细节应该依赖于抽象。
  5. 接口隔离原则(Interface Segregation Principle,ISP):客户端不应该依赖于它不需要的接口。一个类对另一个类的依赖应该建立在最小的接口数量上。
  6. 迪米特法则(Law of Demeter,LoD):一个对象应该对其他对象有尽可能少的了解,不和陌生类发生关系,只和朋友类发生关系。

面向对象设计原则

  • 组合优于及继承
  • 最小化接口暴露
  • 消除代码重复:
  • 工厂模式+模板方法模式
    策略模式
    注解+反射
    重复出现三次,要抽象了
  • 把函数写短,越短越好。
  • 分离关注点,发现的关注点越多越好,粒度越小越好。
  • 识别对象的不同角色,设计小接口
  • 基于行为进行封装,不要暴露实现细节,最小化接口暴露。
  • 依赖于构建出来的抽象,而不是具体类。面向对象设计和实现:
    1.划分职责识别类
    2.定义属性和方法
    3.定义类之间的交互关系
    4.组装类并提供执行入口

工厂+策略模式

首先定义一个枚举类 ExecutorType

public enum ExecutorType {
    TYPE1,
    TYPE2,
}

定义Executor接口和实现

public interface Executor {
    void execute();
    ExecutorType getType(); // 修改返回值为枚举类型
}

@Component
public class ExecutorImpl1 implements Executor {
    @Override
    public void execute() {
        System.out.println("执行实现类1的操作");
    }

    @Override
    public ExecutorType getType() {
        return ExecutorType.TYPE1;
    }
}

@Component
public class ExecutorImpl2 implements Executor {
    @Override
    public void execute() {
        System.out.println("执行实现类2的操作");
    }

    @Override
    public ExecutorType getType() {
        return ExecutorType.TYPE2;
    }
}

初始化类ExecutorInitializer,使用map构造实现类工厂

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

@Component
public class ExecutorInitializer implements BeanPostProcessor {

    private final Map<ExecutorType, Executor> executorMap = new HashMap<>();

    @Autowired
    private void addExecutor(Executor executor) {
        executorMap.put(executor.getType(), executor);
    }

    public Executor getExecutor(ExecutorType type) {
        return executorMap.get(type);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof Executor) {
            addExecutor((Executor) bean);
        }
        return bean;
    }
}

在服务类中,我们使用这个初始化类来获取实现类的实例

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class OrderService {

    @Autowired
    private ExecutorInitializer executorInitializer;

    public void executeByType(ExecutorType type) {
        Executor executor = executorInitializer.getExecutor(type);
        if (executor != null) {
            executor.execute();
        } else {
            System.out.println("未找到对应类型的执行器");
        }
    }
}

状态机模式

spring-statemachine使用

  • 引入maven依赖
<!--状态机-->
        <dependency>
            <groupId>org.springframework.statemachine</groupId>
            <artifactId>spring-statemachine-starter</artifactId>
            <version>2.2.0.RELEASE</version>
        </dependency>
  • 定义状态机的状态与事件(OrderState,OrderEvents)

OrderState:

public enum OrderState {
    UNPAID,                 // 待支付
    WAITING_FOR_RECEIVE,    // 待收货
    DONE                    // 结束
}

OrderEvents:

public enum OrderEvents {
    PAY,        // 支付
    RECEIVE     // 收货
}
  • 将状态与事件进行绑定(StateMachineConfig)
@Configuration
@EnableStateMachine(name = "StateMachineConfig")
public class StateMachineConfig extends EnumStateMachineConfigurerAdapter<OrderState, OrderEvents> {

    private Logger logger = LoggerFactory.getLogger(getClass());
    //定义初始状态
    @Override
    public void configure(StateMachineStateConfigurer<OrderState, OrderEvents> states)
            throws Exception {
        states
            .withStates()
                .initial(OrderState.UNPAID)
                .states(EnumSet.allOf(OrderState.class));
    }
    //状态转换过程 触发什么事件就转换为什么状态
    @Override
    public void configure(StateMachineTransitionConfigurer<OrderState, OrderEvents> transitions)
            throws Exception {
        transitions
            .withExternal()
                .source(OrderState.UNPAID).target(OrderState.WAITING_FOR_RECEIVE)
                .event(OrderEvents.PAY)
                .and()
            .withExternal()
                .source(OrderState.WAITING_FOR_RECEIVE).target(OrderState.DONE)
                .event(OrderEvents.RECEIVE);
    }
}
  • 将事件监听触发与配置类进行配置(EventListener)
@Component
@WithStateMachine(name = "StateMachineConfig")
public class EventListener {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @OnTransition(target = "UNPAID")
    public boolean create(Message<Order> order) {     // 创建订单逻辑
        logger.info("订单创建,待支付");
        return true;
    }

    @OnTransition(source = "UNPAID", target = "WAITING_FOR_RECEIVE")
    public boolean pay(Message<Order> order) {
        // 支付逻辑 从redis根据order 来进行处理
        logger.info("用户完成支付,待收货");
        return true;
    }

    @OnTransition(source = "WAITING_FOR_RECEIVE", target = "DONE")
    public boolean receive(Message<Order> order) {     //从redis中根据传入的order 来查询当前订单 并业务处理
        logger.info("用户已收货,订单完成");
        return true;
    }

}
  • 启动测试
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
    public DemoApplication(StateMachine<OrderState, OrderEvents> stateMachine) {
        this.stateMachine = stateMachine;
    }

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
    private final StateMachine<OrderState, OrderEvents> stateMachine;

    @Override
    public void run(String... args) throws Exception {
        Order order=new Order("测试",0);
        // 使用 MessageBuilder 创建消息并设置负载和头信息
        Message message = MessageBuilder
                .withPayload(OrderEvents.PAY)
                .setHeader("order", order)
                .build();
        // 发送消息给状态机
        stateMachine.start();
        stateMachine.sendEvent(message);
    }
}

模板方法

抽象模板类AbstractTemplate定义算法骨架,类型为final类型,需要子类实现的定义为protected abstract 类型。

// 抽象模板类
abstract class AbstractTemplate {

    // 模板方法,定义了算法的骨架
    public final void templateMethod() {
        step1();
        step2();
        step3();
    }

    // 基本方法,由子类实现
    protected abstract void step1();

    // 基本方法,由子类实现
    protected abstract void step2();

    // 基本方法,由子类实现
    protected abstract void step3();
}

// 具体子类1
class ConcreteClass1 extends AbstractTemplate {

    @Override
    protected void step1() {
        System.out.println("ConcreteClass1: Step 1");
    }

    @Override
    protected void step2() {
        System.out.println("ConcreteClass1: Step 2");
    }

    @Override
    protected void step3() {
        System.out.println("ConcreteClass1: Step 3");
    }
}

// 具体子类2
class ConcreteClass2 extends AbstractTemplate {

    @Override
    protected void step1() {
        System.out.println("ConcreteClass2: Step 1");
    }

    @Override
    protected void step2() {
        System.out.println("ConcreteClass2: Step 2");
    }

    @Override
    protected void step3() {
        System.out.println("ConcreteClass2: Step 3");
    }
}

spring boot使用示例

@SpringBootApplication
public class Application implements CommandLineRunner {

    @Autowired
    private ConcreteClass1 concreteClass1;

    @Autowired
    private ConcreteClass2 concreteClass2;

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        concreteClass1.templateMethod();
        concreteClass2.templateMethod();
    }

标签:void,class,println,protected,Override,设计模式,public
From: https://www.cnblogs.com/caohuajin/p/18152912

相关文章

  • keycloak~jwks-rsa中使用的设计模式
    com.auth0.jwk组织下面的jwks-rsa包,主要实现的是通过公钥对jwt的签名进行验证,在这个包中,它使用了包装器的设计模式,对默认的jwks提供者添加了一缓存的支持,通过建立一个GuavaCachedJwkProvider类,传入一个默认的UrlJwkProvider来将这个Provider进行包装,让它具有缓存的能力!包装器模式......
  • Java设计模式-责任链模式,应用接口多个参数验证,订单多个费用的计算
    Java设计模式-责任链模式,应用接口多个参数验证,订单多个费用的计算1.定义请求和返回对象的上下文对象packagecom.example.core.mydemo.java.filter;importjava.time.LocalDateTime;publicclassOrderReqContext{/***租客会员号*/StringmemNo;......
  • 工程中实践的微服务设计模式
    最近在读《微服务架构设计模式》,开始的时候我非常的好奇,因为在我印象中,设计模式是常说的那23种设计模式,而微服务的设计模式又是什么呢?这个问题也留给大家,在文末我会附上我对这个问题的理解。本次文章的内容主要是工作中对微服务设计模式的应用,希望能对大家有所启发。事务发件箱......
  • 23种设计模式彩图-设计模式之禅
    《TheZenofDesignPatterns》—《设计模式之禅》书中的23种设计模式彩图:......
  • 什么是观察者设计模式?
    什么是观察者观察者模式的主要角色包括:主题(Subject):也称为被观察者或可观察对象。它维护了一系列观察者对象,并提供方法用于注册、删除和通知观察者。当主题的状态发生改变时,它会通知所有注册的观察者。观察者(Observer):观察主题的对象。观察者定义了一个更新方法,主题在状态......
  • day11_我的Java学习笔记 (static_静态成员变量+静态成员方法_工具类、代码块_静态代码
    0.面向对象进阶1.static静态关键字1.1static是什么,static修饰成员变量的用法Java成员变量成员方法Python类(对象)属性类(对象)方法static修饰成员变量的应用:在线人数统计1.2static修饰成员变量的内存原理1.3static修饰成员方法的基本......
  • 基于C语言的面向对象设计模式(持续更新)
    前言首先这篇文章只是初步的尝试,不涉及过于高深的编程技巧;同时需要表明的是,面向对象只是一种思想,不局限于什么样的编程语言,不可否认的是基于面向对象特性而设计的语言确实要比面向过程式的语言更加容易进行抽象和统筹,可以说面向对象的设计模式可以很大程度上摆脱过程的实例,但要论......
  • 设计模式概述
    学习设计模式的目的(1)应对面试设计模式是程序员的基本功,因此是面试中常考察的知识点。(2)写出高质量的代码学好数据结构与算法目的是写出高效的代码,学好设计模式则是为写出高质量的代码。(3)提高复杂代码的设计和开发能力掌握好设计模式才能在开发复杂系统时写出易扩展、易用......
  • 03-JAVA设计模式-代理模式详解
    代理模式什么是代理模式Java代理模式是一种常用的设计模式,主要用于在不修改现有类代码的情况下,为该类添加一些新的功能或行为。代理模式涉及到一个代理类和一个被代理类(也称为目标对象)。代理类负责控制对目标对象的访问,并可以在访问前后添加一些额外的操作。核心作用:通......
  • .NET 设计模式—装饰器模式(Decorator Pattern)
    简介装饰者模式(DecoratorPattern)是一种结构型设计模式,它允许你在不改变对象接口的前提下,动态地将新行为附加到对象上。这种模式是通过创建一个包装(或装饰)对象,将要被装饰的对象包裹起来,从而实现对原有对象功能的增强和扩展。角色Component(组件):定义了一个抽象接口,可以是抽象......