springboot使用的设计模式

设计模式是在软件设计中常用的一些通用解决方案。在开发商城编码时,以下设计模式可能会有用:

工厂模式(Factory Pattern):

用于创建对象的模式。在商城中,可能会涉及到创建不同类型的商品、订单等对象,工厂模式可以帮助你将对象的创建过程抽象出来,使得系统更加灵活。

单例模式(Singleton Pattern):

保证一个类仅有一个实例,并提供一个访问它的全局访问点。在商城中,可能会涉及到一些全局状态或配置信息,使用单例模式可以确保全局状态的一致性。

观察者模式(Observer Pattern):

用于定义一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。在商城中,订单状态的改变、库存的变化等可以使用观察者模式。

策略模式(Strategy Pattern):

定义一系列算法,将它们封装起来,并且使它们可以互相替换。在商城中,支付方式、促销策略等可以考虑使用策略模式,使得系统更加灵活。

模板方法模式(Template Method Pattern):

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。在商城中,订单处理流程、商品上架过程等可以使用模板方法模式。

装饰器模式(Decorator Pattern):

动态地给一个对象添加一些额外的职责。在商城中,可能会有一些商品有附加的服务或者特性,装饰器模式可以帮助你动态地添加这些功能。

命令模式(Command Pattern):

将请求封装成对象,以便使用不同的请求、队列和日志来参数化其他对象。在商城中,可以使用命令模式来处理一些用户的操作,比如撤销、重做等。

状态模式(State Pattern):

允许对象在其内部状态改变时改变它的行为。在商城中,订单状态的变化可以考虑使用状态模式。

代理模式(Proxy Pattern):

为其他对象提供一种代理以控制对这个对象的访问。在商城中,可以使用代理模式来控制对某些敏感操作的访问权限。

这些设计模式可以根据实际业务需求来选择使用,也可以根据项目的规模和复杂性来决定是否引入。设计模式不是一种强制性的规范,而是根据具体情况灵活选择的一种开发经验。

工厂模式可以用于创建不同类型的商品和订单,以提高系统的灵活性。下面给出一个简单的 Java 实例,演示如何使用工厂模式创建不同类型的商品和订单。

首先,定义商品接口和具体商品类:

// 商品接口

interface Product {

    void display();

}

// 具体商品类 A

class ProductA implements Product {

    @Override

    public void display() {

        System.out.println("Product A");

    }

}

// 具体商品类 B

class ProductB implements Product {

    @Override

    public void display() {

        System.out.println("Product B");

    }

}

然后,定义订单接口和具体订单类:

// 订单接口

interface Order {

    void processOrder();

}

// 具体订单类 A

class OrderA implements Order {

    @Override

    public void processOrder() {

        System.out.println("Processing Order A");

    }

}

// 具体订单类 B

class OrderB implements Order {

    @Override

    public void processOrder() {

        System.out.println("Processing Order B");

    }

}

接下来,定义商品工厂和订单工厂:

// 商品工厂接口

interface ProductFactory {

    Product createProduct();

}

// 具体商品工厂 A

class ProductFactoryA implements ProductFactory {

    @Override

    public Product createProduct() {

        return new ProductA();

    }

}

// 具体商品工厂 B

class ProductFactoryB implements ProductFactory {

    @Override

    public Product createProduct() {

        return new ProductB();

    }

}

// 订单工厂接口

interface OrderFactory {

    Order createOrder();

}

// 具体订单工厂 A

class OrderFactoryA implements OrderFactory {

    @Override

    public Order createOrder() {

        return new OrderA();

    }

}

// 具体订单工厂 B

class OrderFactoryB implements OrderFactory {

    @Override

    public Order createOrder() {

        return new OrderB();

    }

}

最后,使用工厂创建商品和订单:

public class FactoryPatternExample {

    public static void main(String[] args) {

        // 创建商品 A

        ProductFactory productFactoryA = new ProductFactoryA();

        Product productA = productFactoryA.createProduct();

        productA.display();

        // 创建订单 B

        OrderFactory orderFactoryB = new OrderFactoryB();

        Order orderB = orderFactoryB.createOrder();

        orderB.processOrder();

    }

}

这个示例中,可以根据需要选择不同的商品工厂和订单工厂,从而创建不同类型的商品和订单。这样的设计使得系统更加灵活,可以方便地扩展和修改。

在一个实际的应用中,Spring 通常与数据库交互,可以使用工厂模式来创建数据库相关的实例。以下是一个简单的例子,演示如何使用 Spring 和工厂模式创建数据库连接。

假设有一个数据库工厂接口和两个数据库连接实现类,分别是 MySQL 和 PostgreSQL:

// 数据库工厂接口

public interface DatabaseFactory {

    DatabaseConnector createDatabaseConnector();

}

// MySQL 数据库连接实现类

public class MySQLDatabaseFactory implements DatabaseFactory {

    @Override

    public DatabaseConnector createDatabaseConnector() {

        return new MySQLDatabaseConnector();

    }

}

// PostgreSQL 数据库连接实现类

public class PostgreSQLDatabaseFactory implements DatabaseFactory {

    @Override

    public DatabaseConnector createDatabaseConnector() {

        return new PostgreSQLDatabaseConnector();

    }

}

// 数据库连接接口

public interface DatabaseConnector {

    void connect();

}

// MySQL 数据库连接实现类

public class MySQLDatabaseConnector implements DatabaseConnector {

    @Override

    public void connect() {

        System.out.println("Connected to MySQL Database");

        // 连接 MySQL 数据库的具体逻辑

    }

}

// PostgreSQL 数据库连接实现类

public class PostgreSQLDatabaseConnector implements DatabaseConnector {

    @Override

    public void connect() {

        System.out.println("Connected to PostgreSQL Database");

        // 连接 PostgreSQL 数据库的具体逻辑

    }

}

然后,通过 Spring 配置文件将工厂模式整合到 Spring 容器中:

<!-- Spring 配置文件 -->

<beans xmlns="http://www.springframework.org/schema/beans"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xsi:schemaLocation="http://www.springframework.org/schema/beans

                           http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 注册 MySQL 数据库工厂 -->

    <bean id="mysqlDatabaseFactory" class="com.example.factory.MySQLDatabaseFactory"/>

    <!-- 注册 PostgreSQL 数据库工厂 -->

    <bean id="postgreSQLDatabaseFactory" class="com.example.factory.PostgreSQLDatabaseFactory"/>

    <!-- 注册数据库连接服务 -->

    <bean id="databaseService" class="com.example.service.DatabaseService">

        <property name="databaseFactory" ref="mysqlDatabaseFactory"/>

    </bean>

</beans>

最后,编写一个简单的服务类,通过 Spring 注入工厂实例并使用工厂模式创建数据库连接:

public class DatabaseService {

    private DatabaseFactory databaseFactory;

    // Spring 注入数据库工厂实例

    public void setDatabaseFactory(DatabaseFactory databaseFactory) {

        this.databaseFactory = databaseFactory;

    }

    // 使用工厂模式创建数据库连接

    public void connectToDatabase() {

        DatabaseConnector connector = databaseFactory.createDatabaseConnector();

        connector.connect();

    }

}

这样,通过配置不同的数据库工厂实例,可以在运行时切换数据库连接的实现,而不需要修改服务类的代码。这是一个简单的例子,实际应用中可能需要更多的细节和配置,以适应复杂的业务需求。

在实际应用中,将工厂模式与数据库和 Spring 结合的一个典型场景是通过 Spring 的依赖注入(DI)来实例化不同类型的商品和订单,并且这些商品和订单信息通常存储在数据库中。下面是一个简单的示例,演示如何使用工厂模式、Spring、和数据库。

假设有一个简单的商城系统,其中包括商品和订单。首先,定义商品和订单的接口以及实现类:

// 商品接口

public interface Product {

    void display();

}

// 具体商品类 A

public class ProductA implements Product {

    @Override

    public void display() {

        System.out.println("Product A");

    }

}

// 订单接口

public interface Order {

    void processOrder();

}

// 具体订单类 A

public class OrderA implements Order {

    @Override

    public void processOrder() {

        System.out.println("Processing Order A");

    }

}

然后,定义商品和订单的工厂接口和实现类:

// 商品工厂接口

public interface ProductFactory {

    Product createProduct();

}

// 具体商品工厂 A

public class ProductFactoryA implements ProductFactory {

    @Override

    public Product createProduct() {

        return new ProductA();

    }

}

// 订单工厂接口

public interface OrderFactory {

    Order createOrder();

}

// 具体订单工厂 A

public class OrderFactoryA implements OrderFactory {

    @Override

    public Order createOrder() {

        return new OrderA();

    }

}

接下来,创建数据库表存储商品和订单信息。在这里,我们简单地使用内存数据库 H2,并使用 Spring 的 JdbcTemplate 进行数据库操作。

// 商品数据库表

CREATE TABLE product (

    id INT PRIMARY KEY,

    name VARCHAR(255)

);

// 订单数据库表

CREATE TABLE order_table (

    id INT PRIMARY KEY,

    description VARCHAR(255)

);

接着,创建 Spring 配置文件,配置数据库连接和 Bean 的声明:

<!-- Spring 配置文件 -->

<beans xmlns="http://www.springframework.org/schema/beans"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xmlns:context="http://www.springframework.org/schema/context"

       xsi:schemaLocation="http://www.springframework.org/schema/beans

                           http://www.springframework.org/schema/beans/spring-beans.xsd

                           http://www.springframework.org/schema/context

                           http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 数据库配置 -->

    <context:property-placeholder location="classpath:application.properties"/>

    <!-- 数据源配置 -->

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

        <property name="driverClassName" value="${jdbc.driverClassName}"/>

        <property name="url" value="${jdbc.url}"/>

        <property name="username" value="${jdbc.username}"/>

        <property name="password" value="${jdbc.password}"/>

    </bean>

    <!-- JdbcTemplate 配置 -->

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">

        <property name="dataSource" ref="dataSource"/>

    </bean>

    <!-- 商品工厂 Bean 配置 -->

    <bean id="productFactoryA" class="com.example.factory.ProductFactoryA"/>

    <!-- 订单工厂 Bean 配置 -->

    <bean id="orderFactoryA" class="com.example.factory.OrderFactoryA"/>

    <!-- 商品服务 Bean 配置 -->

    <bean id="productService" class="com.example.service.ProductService">

        <property name="productFactory" ref="productFactoryA"/>

    </bean>

    <!-- 订单服务 Bean 配置 -->

    <bean id="orderService" class="com.example.service.OrderService">

        <property name="orderFactory" ref="orderFactoryA"/>

    </bean>

</beans>

在 application.properties 中配置数据库连接信息:

jdbc.driverClassName=org.h2.Driver

jdbc.url=jdbc:h2:mem:testdb

jdbc.username=sa

jdbc.password=

最后,创建商品和订单的服务类,通过 Spring 注入工厂实例并进行数据库操作:

// 商品服务类

public class ProductService {

    private ProductFactory productFactory;

    public void setProductFactory(ProductFactory productFactory) {

        this.productFactory = productFactory;

    }

    public void createAndDisplayProduct() {

        Product product = productFactory.createProduct();

        product.display();

    }

}

// 订单服务类

public class OrderService {

    private OrderFactory orderFactory;

    public void setOrderFactory(OrderFactory orderFactory) {

        this.orderFactory = orderFactory;

    }

    public void createAndProcessOrder() {

        Order order = orderFactory.createOrder();

        order.processOrder();

    }

}

通过上述配置,你可以在运行时轻松切换商品和订单的具体实现,并且通过数据库存储商品和订单信息,实现了工厂模式与 Spring 和数据库的集成。请注意,这只是一个简单的示例,实际应用中可能需要更多的配置和处理。

在 Spring Boot 中,工厂模式、数据库操作可以更加简化和集成。下面是一个简单的示例,演示如何在 Spring Boot 中使用工厂模式创建不同类型的商品和订单,并且将商品和订单信息存储在数据库中。

首先,定义商品和订单的实体类以及数据库操作接口:

// 商品实体类

@Entity

public class Product {

    @Id

    @GeneratedValue(strategy = GenerationType.IDENTITY)

    private Long id;

    private String name;

    // getters and setters

}

// 订单实体类

@Entity

public class Order {

    @Id

    @GeneratedValue(strategy = GenerationType.IDENTITY)

    private Long id;

    private String description;

    // getters and setters

}

// 商品数据库操作接口

public interface ProductRepository extends JpaRepository<Product, Long> {

}

// 订单数据库操作接口

public interface OrderRepository extends JpaRepository<Order, Long> {

}

然后,定义商品和订单的工厂接口和实现类:

// 商品工厂接口

public interface ProductFactory {

    Product createProduct();

}

// 具体商品工厂 A

@Component

public class ProductFactoryA implements ProductFactory {

    @Override

    public Product createProduct() {

        Product product = new Product();

        product.setName("Product A");

        return product;

    }

}

// 订单工厂接口

public interface OrderFactory {

    Order createOrder();

}

// 具体订单工厂 A

@Component

public class OrderFactoryA implements OrderFactory {

    @Override

    public Order createOrder() {

        Order order = new Order();

        order.setDescription("Order A");

        return order;

    }

}

接下来,通过 Spring Boot 自动配置,创建数据库表和进行数据库操作。Spring Boot 会自动识别实体类并创建相应的数据表。

在 application.properties 中配置数据库连接信息:

spring.datasource.url=jdbc:h2:mem:testdb

spring.datasource.driver-class-name=org.h2.Driver

spring.datasource.username=sa

spring.datasource.password=

spring.h2.console.enabled=true

然后,创建商品和订单的服务类,通过 Spring 注入工厂实例,并通过数据库操作存储商品和订单信息:

// 商品服务类

@Service

public class ProductService {

    private final ProductFactory productFactory;

    private final ProductRepository productRepository;

    @Autowired

    public ProductService(ProductFactory productFactory, ProductRepository productRepository) {

        this.productFactory = productFactory;

        this.productRepository = productRepository;

    }

    public void createAndSaveProduct() {

        Product product = productFactory.createProduct();

        productRepository.save(product);

    }

}

// 订单服务类

@Service

public class OrderService {

    private final OrderFactory orderFactory;

    private final OrderRepository orderRepository;

    @Autowired

    public OrderService(OrderFactory orderFactory, OrderRepository orderRepository) {

        this.orderFactory = orderFactory;

        this.orderRepository = orderRepository;

    }

    public void createAndSaveOrder() {

        Order order = orderFactory.createOrder();

        orderRepository.save(order);

    }

}

最后,在启动类中调用服务类的方法进行演示:

@SpringBootApplication

public class FactoryPatternApplication implements CommandLineRunner {

    @Autowired

    private ProductService productService;

    @Autowired

    private OrderService orderService;

    public static void main(String[] args) {

        SpringApplication.run(FactoryPatternApplication.class, args);

    }

    @Override

    public void run(String... args) {

        productService.createAndSaveProduct();

        orderService.createAndSaveOrder();

    }

}

这个简单的示例演示了如何在 Spring Boot 中使用工厂模式创建不同类型的商品和订单,并将它们存储在数据库中。这样的设计使得系统更加灵活,可以方便地扩展和修改。

在 Spring Boot 中使用观察者模式来处理订单状态的改变和库存的变化是一种灵活的设计。观察者模式允许一个对象(被观察者)维护一系列依赖它的对象(观察者),当被观察者的状态发生变化时,所有注册的观察者都会得到通知并执行相应的操作。

以下是一个简单的示例,演示如何在 Spring Boot 中使用观察者模式处理订单状态的改变和库存的变化:

首先,定义订单和库存的实体类:

// 订单实体类

public class Order {

    private Long id;

    private String status;

    // getters and setters

}

// 库存实体类

public class Inventory {

    private Long productId;

    private int quantity;

    // getters and setters

}

然后,定义观察者接口和实现类:

// 观察者接口

public interface OrderObserver {

    void update(Order order);

}

// 具体观察者类 - 处理订单状态改变

@Component

public class OrderStatusObserver implements OrderObserver {

    @Override

    public void update(Order order) {

        System.out.println("Order Status Observer: Order " + order.getId() + " has been updated to " + order.getStatus());

        // 具体处理订单状态改变的逻辑

    }

}

// 具体观察者类 - 处理库存变化

@Component

public class InventoryObserver implements OrderObserver {

    @Override

    public void update(Order order) {

        System.out.println("Inventory Observer: Updating inventory for Order " + order.getId());

        // 具体处理库存变化的逻辑

    }

}

接下来,定义被观察者(订单服务类):

// 被观察者 - 订单服务类

@Service

public class OrderService {

    private List<OrderObserver> observers = new ArrayList<>();

    // 注册观察者

    public void addObserver(OrderObserver observer) {

        observers.add(observer);

    }

    // 模拟订单状态改变的操作

    public void updateOrderStatus(Order order, String newStatus) {

        order.setStatus(newStatus);

        notifyObservers(order);

    }

    // 通知所有观察者

    private void notifyObservers(Order order) {

        for (OrderObserver observer : observers) {

            observer.update(order);

        }

    }

}

最后,在 Spring Boot 启动类中进行演示:

@SpringBootApplication

public class ObserverPatternApplication implements CommandLineRunner {

    @Autowired

    private OrderService orderService;

    public static void main(String[] args) {

        SpringApplication.run(ObserverPatternApplication.class, args);

    }

    @Override

    public void run(String... args) {

        // 创建订单

        Order order = new Order();

        order.setId(1L);

        order.setStatus("Pending");

        // 注册观察者

        orderService.addObserver(new OrderStatusObserver());

        orderService.addObserver(new InventoryObserver());

        // 模拟订单状态改变

        orderService.updateOrderStatus(order, "Shipped");

    }

}

在这个简单的示例中,OrderService 充当被观察者,而 OrderStatusObserver 和 InventoryObserver 分别充当观察者。当订单状态发生变化时,被观察者通知所有观察者进行相应的操作。这种设计可以轻松地添加新的观察者以处理其他业务逻辑,实现了解耦和灵活性。在实际应用中,可以根据具体需求扩展和优化这个设计。

使用策略模式来处理支付方式和促销策略是一个很好的设计选择。策略模式允许定义一系列算法,将每个算法封装起来,并使它们可以相互替换。在 Spring Boot 中,你可以结合数据库来存储支付方式和促销策略的信息,并使用策略模式来实现动态选择。

以下是一个简单的示例,演示如何在 Spring Boot 中使用策略模式处理支付方式和促销策略:

首先,定义支付方式和促销策略的接口:

public interface PaymentStrategy {

    void pay(double amount);

}

// 促销策略接口

public interface PromotionStrategy {

    double applyDiscount(double originalPrice);

}

然后,定义具体的支付方式和促销策略实现类:

// 具体支付方式类 - 支付宝支付

@Component

public class AlipayPayment implements PaymentStrategy {

    @Override

    public void pay(double amount) {

        System.out.println("Using Alipay to pay: " + amount);

        // 具体支付逻辑

    }

}

// 具体支付方式类 - 微信支付

@Component

public class WeChatPayment implements PaymentStrategy {

    @Override

    public void pay(double amount) {

        System.out.println("Using WeChat to pay: " + amount);

        // 具体支付逻辑

    }

}

// 具体促销策略类 - 打折促销

@Component

public class DiscountPromotion implements PromotionStrategy {

    @Override

    public double applyDiscount(double originalPrice) {

        System.out.println("Applying discount promotion");

        return originalPrice * 0.8; // 打八折

    }

}

// 具体促销策略类 - 满减促销

@Component

public class CashBackPromotion implements PromotionStrategy {

    @Override

    public double applyDiscount(double originalPrice) {

        System.out.println("Applying cash back promotion");

        if (originalPrice >= 100) {

            return originalPrice - 10; // 满100减10

        } else {

            return originalPrice;

        }

    }

}

接下来,定义订单服务类,通过 Spring 注入支付方式和促销策略:

// 订单服务类

@Service

public class OrderService {

    @Autowired

    private PaymentStrategy paymentStrategy;

    @Autowired

    private PromotionStrategy promotionStrategy;

    // 模拟订单结算

    public void checkout(double originalPrice) {

        double discountedPrice = promotionStrategy.applyDiscount(originalPrice);

        paymentStrategy.pay(discountedPrice);

    }

}

最后,在 Spring Boot 启动类中进行演示:

@SpringBootApplication

public class StrategyPatternApplication implements CommandLineRunner {

    @Autowired

    private OrderService orderService;

    public static void main(String[] args) {

        SpringApplication.run(StrategyPatternApplication.class, args);

    }

    @Override

    public void run(String... args) {

        // 模拟订单结算

        orderService.checkout(100);

    }

}

在这个简单的示例中,OrderService 充当了策略模式的上下文(Context),通过 Spring 注入具体的支付方式和促销策略实现类。在运行时,你可以轻松地替换具体的支付方式和促销策略,实现了动态选择和解耦。在实际应用中,可以根据需求扩展和优化这个设计,例如从数据库中动态加载支付方式和促销策略。

方法一:使用配置文件

在 application.properties 或 application.yml 中配置策略的名称,然后通过 @Value 注解注入,并根据配置的名称来选择具体的实现类。

# 配置支付方式和促销策略的名称

payment.strategy=alipay

promotion.strategy=discount

java

复制代码

@Component

public class OrderService {

    @Autowired

    @Qualifier("${payment.strategy}Payment")

    private PaymentStrategy paymentStrategy;

    @Autowired

    @Qualifier("${promotion.strategy}Promotion")

    private PromotionStrategy promotionStrategy;

    // 其他代码...

}

方法二:使用条件判断

通过条件判断来选择具体的实现类。这可能涉及到一些业务逻辑或者外部参数的判断。

@Component

public class OrderService {

    @Autowired

    private PaymentStrategy alipayPayment;

    @Autowired

    private PaymentStrategy wechatPayment;

    @Autowired

    private PromotionStrategy discountPromotion;

    @Autowired

    private PromotionStrategy cashBackPromotion;

    // 根据条件判断选择具体的实现类

    public void checkout(double originalPrice, String paymentMethod, String promotionType) {

        PaymentStrategy selectedPaymentStrategy;

        PromotionStrategy selectedPromotionStrategy;

        if ("alipay".equals(paymentMethod)) {

            selectedPaymentStrategy = alipayPayment;

        } else if ("wechat".equals(paymentMethod)) {

            selectedPaymentStrategy = wechatPayment;

        } else {

            throw new IllegalArgumentException("Invalid payment method");

        }

        if ("discount".equals(promotionType)) {

            selectedPromotionStrategy = discountPromotion;

        } else if ("cashback".equals(promotionType)) {

            selectedPromotionStrategy = cashBackPromotion;

        } else {

            throw new IllegalArgumentException("Invalid promotion type");

        }

        double discountedPrice = selectedPromotionStrategy.applyDiscount(originalPrice);

        selectedPaymentStrategy.pay(discountedPrice);

    }

}

这两种方法都允许在运行时根据配置或条件选择具体的实现类。选择方法取决于你的具体需求和设计风格。在实际应用中,你可能需要更复杂的逻辑,比如从数据库中动态加载实现类的信息。

当使用条件判断时,可以考虑进一步优化以提高代码的灵活性和可维护性。以下是一些可能的优化方案:

1. 使用 Map 存储策略实现类

将策略实现类存储在一个 Map 中,通过配置或者其他方式初始化这个 Map。这样可以避免大量的条件判断,并提高代码的可维护性。

@Component

public class OrderService {

    private final Map<String, PaymentStrategy> paymentStrategies = new HashMap<>();

    private final Map<String, PromotionStrategy> promotionStrategies = new HashMap<>();

    @Autowired

    public OrderService(Map<String, PaymentStrategy> paymentStrategies, Map<String, PromotionStrategy> promotionStrategies) {

        this.paymentStrategies.putAll(paymentStrategies);

        this.promotionStrategies.putAll(promotionStrategies);

    }

    // 根据条件选择具体的实现类

    public void checkout(double originalPrice, String paymentMethod, String promotionType) {

        PaymentStrategy selectedPaymentStrategy = paymentStrategies.get(paymentMethod);

        PromotionStrategy selectedPromotionStrategy = promotionStrategies.get(promotionType);

        if (selectedPaymentStrategy == null) {

            throw new IllegalArgumentException("Invalid payment method");

        }

        if (selectedPromotionStrategy == null) {

            throw new IllegalArgumentException("Invalid promotion type");

        }

        double discountedPrice = selectedPromotionStrategy.applyDiscount(originalPrice);

        selectedPaymentStrategy.pay(discountedPrice);

    }

}

2. 使用枚举来表示策略类型

定义枚举来表示策略类型,将配置信息映射到枚举值,然后通过枚举值选择具体的策略实现类。

public enum PaymentMethod {

    ALIPAY, WECHAT;

}

public enum PromotionType {

    DISCOUNT, CASHBACK;

}

@Component

public class OrderService {

    private final Map<PaymentMethod, PaymentStrategy> paymentStrategies = new EnumMap<>(PaymentMethod.class);

    private final Map<PromotionType, PromotionStrategy> promotionStrategies = new EnumMap<>(PromotionType.class);

    @Autowired

    public OrderService(Map<PaymentMethod, PaymentStrategy> paymentStrategies, Map<PromotionType, PromotionStrategy> promotionStrategies) {

        this.paymentStrategies.putAll(paymentStrategies);

        this.promotionStrategies.putAll(promotionStrategies);

    }

    // 根据枚举值选择具体的实现类

    public void checkout(double originalPrice, PaymentMethod paymentMethod, PromotionType promotionType) {

        PaymentStrategy selectedPaymentStrategy = paymentStrategies.get(paymentMethod);

        PromotionStrategy selectedPromotionStrategy = promotionStrategies.get(promotionType);

        if (selectedPaymentStrategy == null) {

            throw new IllegalArgumentException("Invalid payment method");

        }

        if (selectedPromotionStrategy == null) {

            throw new IllegalArgumentException("Invalid promotion type");

        }

        double discountedPrice = selectedPromotionStrategy.applyDiscount(originalPrice);

        selectedPaymentStrategy.pay(discountedPrice);

    }

}

这两种优化方案可以提高代码的可读性和可维护性,同时减少了条件判断的数量。选择哪种方式取决于项目的具体需求和团队的开发风格。

模板方法模式(Template Method Pattern):

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。在商城中,订单处理流程、商品上架过程等可以使用模板方法模式。

装饰器模式(Decorator Pattern):

动态地给一个对象添加一些额外的职责。在商城中,可能会有一些商品有附加的服务或者特性,装饰器模式可以帮助你动态地添加这些功能。

命令模式(Command Pattern):

将请求封装成对象,以便使用不同的请求、队列和日志来参数化其他对象。在商城中,可以使用命令模式来处理一些用户的操作,比如撤销、重做等。

状态模式(State Pattern):

允许对象在其内部状态改变时改变它的行为。在商城中,订单状态的变化可以考虑使用状态模式。

代理模式(Proxy Pattern):

为其他对象提供一种代理以控制对这个对象的访问。在商城中,可以使用代理模式来控制对某些敏感操作的访问权限  分别结合数据库和springboot

模板方法模式(Template Method Pattern)

在商城中,模板方法模式可以用于定义一些订单处理流程或商品上架过程。以下是一个简单的示例:

java

复制代码

// 抽象模板类

public abstract class OrderProcessingTemplate {

    public final void processOrder() {

        validateOrder();

        performPayment();

        dispatchOrder();

        sendNotification();

    }

    protected abstract void validateOrder();

    protected abstract void performPayment();

    protected abstract void dispatchOrder();

    protected abstract void sendNotification();

}

// 具体订单处理类

@Component

public class OnlineOrderProcessing extends OrderProcessingTemplate {

    @Override

    protected void validateOrder() {

        // 具体的订单验证逻辑

        System.out.println("Validating online order...");

    }

    @Override

    protected void performPayment() {

        // 具体的支付逻辑

        System.out.println("Processing online payment...");

    }

    @Override

    protected void dispatchOrder() {

        // 具体的订单派发逻辑

        System.out.println("Dispatching online order...");

    }

    @Override

    protected void sendNotification() {

        // 具体的通知逻辑

        System.out.println("Sending online order notification...");

    }

}

装饰器模式(Decorator Pattern)

在商城中,装饰器模式可以用于动态地给商品添加一些额外的服务或特性。

java

复制代码

// 商品接口

public interface Product {

    void display();

}

// 具体商品类

@Component

public class ConcreteProduct implements Product {

    @Override

    public void display() {

        System.out.println("Displaying the product");

    }

}

// 装饰器抽象类

public abstract class ProductDecorator implements Product {

    protected Product decoratedProduct;

    public ProductDecorator(Product decoratedProduct) {

        this.decoratedProduct = decoratedProduct;

    }

    @Override

    public void display() {

        decoratedProduct.display();

    }

}

// 具体装饰器类 - 附加服务1

@Component

public class Service1Decorator extends ProductDecorator {

    public Service1Decorator(Product decoratedProduct) {

        super(decoratedProduct);

    }

    @Override

    public void display() {

        super.display();

        addService1();

    }

    private void addService1() {

        System.out.println("Adding additional service 1");

    }

}

命令模式(Command Pattern)

在商城中,命令模式可以用于处理一些用户操作,比如撤销、重做等。

// 命令接口

public interface Command {

    void execute();

}

// 具体命令类

@Component

public class OrderCommand implements Command {

    @Override

    public void execute() {

        // 具体的订单操作逻辑

        System.out.println("Executing order command...");

    }

}

// 调用者类

@Component

public class CommandInvoker {

    private Command command;

    public void setCommand(Command command) {

        this.command = command;

    }

    public void executeCommand() {

        command.execute();

    }

}

状态模式(State Pattern)

在商城中,状态模式可以用于处理订单状态的变化。

java

复制代码

// 订单状态接口

public interface OrderState {

    void processOrder();

}

// 具体订单状态类 - 待支付

@Component

public class PendingPaymentState implements OrderState {

    @Override

    public void processOrder() {

        System.out.println("Processing order in pending payment state...");

    }

}

// 具体订单状态类 - 已支付

@Component

public class PaidState implements OrderState {

    @Override

    public void processOrder() {

        System.out.println("Processing order in paid state...");

    }

}

// 上下文类

@Component

public class OrderContext {

    private OrderState orderState;

    public void setOrderState(OrderState orderState) {

        this.orderState = orderState;

    }

    public void processOrder() {

        orderState.processOrder();

    }

}

代理模式(Proxy Pattern)

在商城中,代理模式可以用于控制对某些敏感操作的访问权限。

// 接口

public interface ProductService {

    void addProduct();

}

// 具体实现类

@Component

public class ProductServiceImpl implements ProductService {

    @Override

    public void addProduct() {

        System.out.println("Adding a new product...");

    }

}

// 代理类

@Component

public class ProductServiceProxy implements ProductService {

    @Autowired

    private ProductService productService;

    @Override

    public void addProduct() {

        // 在具体操作前进行权限验证等操作

        System.out.println("Proxy: Checking user permission...");

        productService.addProduct();

    }

}

这些示例演示了如何在商城中应用这些设计模式,并结合了 Spring Boot 的特性。设计模式的选择取决于具体的需求和业务场景,可以根据实际情况进行调整和扩展。

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

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

相关文章

【C++上层应用】3. 动态内存

文章目录 【 1. new和delete运算符 】1.1 new 分配内存1.2 delete 释放内存1.3 实例 【 2. 数组的动态内存分配 】2.1 一维数组2.2 二维数组2.3 三维数组 【 3. 对象的动态内存分配 】 C 程序中的内存分为两个部分&#xff1a; 栈&#xff1a;在 函数内部 声明的所有变量都将占…

go语言学习之旅之Go语言函数

学无止境&#xff0c;今天继续学习go语言的基础内容 Go语言函数 Go 语言函数定义格式如下 func function_name( [parameter list] ) [return_types] {函数体}函数定义解析 func&#xff1a;函数由 func 开始声明 function_name&#xff1a;函数名称&#xff0c;函数名和参数…

Me-and-My-Girlfriend-1

Me-and-My-Girlfriend-1 一、主机发现和端口扫描 主机发现&#xff0c;靶机地址192.168.80.147 arp-scan -l端口扫描&#xff0c;开放了22、80端口 nmap -A -p- -sV 192.168.80.147二、信息收集 访问80端口 路径扫描 dirsearch -u "http://192.168.80.147/" -e * …

浪潮信息云峦服务器操作系统KeyarchOS体验与实践

写在前面 大家好我是网络豆&#xff0c;一名云计算运维人员&#xff0c;本文将会带大家体验一下浪潮信息服务器操作系统云峦KeyarchOS。看看浪潮信息服务器操作系统云峦KeyarchOS的优势与实践操作如何。 背景了解 KeyarchOS是浪潮信息基于Linux Kernel、OpenAnolis等开源技术…

【Element】el-progress 自定义进度条

一、背景 要求弹窗内显示进度条&#xff0c;根据接口获取当前进度值&#xff0c;间隔5秒调用接口获取最新进度值&#xff0c;当进度值为100时&#xff0c;允许关闭进度条弹窗 二、效果 三、实现步骤 3.1、按钮绑定事件&#xff0c;打开弹窗 <el-button class"cance…

接入电商数据平台官方开放平台API接口获取商品实时信息数据,销量,评论,详情页演示

要接入电商数据平台官方开放平台API接口获取商品实时信息数据、销量、评论和详情页演示&#xff0c;需要按照以下步骤进行操作&#xff1a; 找到可用的API接口&#xff1a;首先&#xff0c;需要找到支持查询商品信息的API接口。可以在电商数据平台的官方开放平台上查找相应的AP…

python tkinter 使用

python tkinter 使用 ython可以使用多种GUI库来创建窗口页面&#xff0c;例如Tkinter、PyQt、wxPython等。 本篇文章主要讲述如何使用tkinter。 1&#xff1a;导入 import tkinter as tk这时如果运行的话会提示&#xff1a; ModuleNotFoundError: No module named ‘tkint…

JVM常见参数总结

JVM是Java应用程序的运行环境&#xff0c;它通过参数配置来控制其行为和性能。在JVM中&#xff0c;有很多参数可以用来调整其运行状态&#xff0c;这些参数可以帮助开发人员根据应用程序的需求进行优化和调整。在本次分享中&#xff0c;作者将介绍一些常见的JVM参数&#xff0c…

弄懂Rust编程中的Trait

1.定义 trait trait 定义了某个特定类型拥有可能与其他类型共享的功能。可以通过 trait 以一种抽象的方式定义共享的行为。可以使用 trait bounds 指定泛型是任何拥有特定行为的类型。 一个类型的行为由其可供调用的方法构成。如果可以对不同类型调用相同的方法的话&#xff…

机器人制作开源方案 | 莲花灯

1. 功能描述 莲花灯是一款基于莲花形象设计的机器人&#xff0c;本文示例将用两种模式来实现莲花灯的亮灭功能。 自主模式&#xff1a;用 光强传感器 控制莲花灯的灯叶开合。暗光情况下灯叶打开&#xff0c;灯亮&#xff1b;强光情况下灯叶闭合&#xff0c;灯灭。 …

webpack环境变量的设置

现在虽然vite比较流行&#xff0c;但对于用node写后端来说&#xff0c;webpack倒是成了一个很好的打包工具&#xff0c;可以很好的保护后端的代码。所以这块的学习还是不能停下来&#xff0c;接下来我们来针对不同的环境做不同的设置写好笔记。 引用场景主要是针对服务器的各种…

python模拟砍价源码详解

以下是一个简单的Python程序&#xff0c;模拟砍价的过程。这个程序假设原始价格是100元&#xff0c;每次砍价砍掉价格的10%&#xff1a; class Item:def __init__(self, original_price):self.original_price original_priceself.current_price original_pricedef bargain(s…

0时区格林威治时间转换手机当地时间-Android

假设传入的是2023-11-01T12:59:10.420987这样的格式 要将格式为2023-11-01T12:59:10.420987的UTC时间字符串转换为Android设备本地时间&#xff0c;您可以使用java.time包中的类&#xff08;在API 26及以上版本中可用&#xff09;。如果您的应用需要支持较低版本的Android&…

docker通过挂载conf文件启动redis

初衷&#xff1a;之前直接在启动脚本中没有挂载配置文件&#xff0c;并且直接设置了密码等&#xff0c;后续要使用集群&#xff0c;苦于无法修改配置&#xff0c;进入redis容器也找不到redis.conf&#xff0c;所以写这个文章用来使用redis的配置&#xff0c;来达到后续都可动态…

pdf转png工具类

pdf转图片的工具类 1、需要引入的包 <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.4</version></dependency> 2、工具类 public static void main(String[] args) {Stri…

华为OD南京研究所二面手撕代码实录:乘电梯的最短时间

乘电梯的最短时间 某公司,每天早上都有很多人去坐电梯,每个人都可能到不同的楼层.同时电梯还有一个容量限制.电梯最多只能带K个人.电梯从第a层到第b层,会花费|a-b|的时间. 现在有N个人,以及知道每个人想要去的地方,请问如何坐电梯,才能使每个人到达到他们对应的楼层,且所花费时…

《微信小程序开发从入门到实战》学习二十四

3.3.12开发创建投票多选投票页面 创建投票多选投票页面和创建单选投票页面没有区别&#xff0c;唯一区别仅在于向服务端发送数据时&#xff0c;告诉服务器这个投票是什么类型的投票。这个类型用三种数据类型表示都可以&#xff0c;分别如下所示&#xff1a; multiple:true/fa…

Json数据格式

json比较可读&#xff0c;通过键值对返回。实现通常有两种方式:一种是自己来构造&#xff0c;也就是用一个对象存储数据&#xff0c;在最后输出时将其json字符串化&#xff1b;第二种是使用 RestController 注解实现json数据返回。 第一种 导入依赖坐标&#xff1a; <depe…

阿里 OSS鉴权访问文件

如果OSS文件设置保护&#xff0c;需要鉴权才能访问&#xff0c;添加请求头鉴权&#xff0c;SDK方法如上&#xff1b; 将鉴权信息和地址、时间返回给前端&#xff0c;前端直接从oss上读取 String filePath "/admin/2023/6/183569314928918546.png"; RequestMessage…

【C++上层应用】6. 信号 / 中断

文章目录 【 1. signal 函数 】【 2. raise函数 】 信号是由操作系统传给进程的 中断&#xff0c;会提早终止一个程序。在 UNIX、LINUX、Mac OS X 或 Windows 系统上&#xff0c;可以通过按 CtrlC 产生中断。有些信号不能被程序捕获&#xff0c;但是下表所列信号可以在程序中捕…