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 的特性。设计模式的选择取决于具体的需求和业务场景,可以根据实际情况进行调整和扩展。
相关文章:
springboot使用的设计模式
设计模式是在软件设计中常用的一些通用解决方案。在开发商城编码时,以下设计模式可能会有用: 工厂模式(Factory Pattern): 用于创建对象的模式。在商城中,可能会涉及到创建不同类型的商品、订单等对象&…...

IP地址定位技术发展与未来趋势
随着互联网的快速发展,人们对网络的需求和依赖程度越来越高。在海量的网络数据传输中,IP地址定位技术作为网络安全与信息追踪的重要手段,其精准度一直备受关注。近年来,随着技术的不断进步,IP地址定位的精准度得到了显…...

AI与交通运输
人工智能(AI)正在改变几乎所有行业,交通运输也不例外。 虽然与某些行业相比,我们运输货物和乘客的方式在过去 50 年里变化相对较小,但人工智能有望引发一场运输革命—如果你正在寻找人工智能的机会,不要错过…...
window.requestAnimationFrame+localStorage+canvas实现跨窗口小球连线效果
文章目录 前言效果代码后言 前言 hello world欢迎来到前端的新世界 😜当前文章系列专栏:前端系列文章 🐱👓博主在前端领域还有很多知识和技术需要掌握,正在不断努力填补技术短板。(如果出现错误,感谢大家…...
使用AndResGuard报错:copy res file not in resources.arsc file:Ezi.xml
Android使用AndResGuard进行资源混淆,压缩。 源码地址:GitHub - shwenzhang/AndResGuard: proguard resource for Android by wechat team 集成完成后编译过程中出现如下错误: 14:57:05 copy res file not in resources.arsc file:IUk.xml…...

插入排序(形象类比)
最近在看riscv手册的时候,里面有一段代码是插入排序,但是单看代码的时候有点迷,没看懂咋操作的,后来又查资料复习了一下,最终才把代码看明白,所以写篇博客记录一下。 插入排序像打扑克牌 这是我听到过比较形…...
ElasticSearch 同步的方式
ElasticSearch 同步的方式 ElasticSearch是一款强大的分布式搜索和分析引擎,支持多种方式同步数据和日志。下面介绍几种常见的同步方式: 1. Logstash Logstash 是 ElasticStack 的一部分,用于收集、处理和转发日志和事件数据。通过配置 Lo…...
easyExcel实现分批导入,动态表头分批导出,以及导出表格样式设置
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.6</version></dependency> 一,分批导入 1.首先配置表格头映射类 Getter Setter EqualsAndHashCode public class …...
Android BottomNavigationView底部菜单栏文字显示问题
1. BottomNavigationView 如果tab栏数据小于等于3个,那么图标和文字都是展示出来; 2. BottomNavigationView 如果tab栏数据大于3个,那么图标会显示出来,但是文字会隐藏; 3. 解决方式: (当底部…...
从零开始学习typescript——运算符(条件运算法、逻辑运算符、类型运算符、位运算)
条件运算符 条件运算符是一个根据条件返回不同运算结果的运算符 关键字:?: 三元运算符 它可以换成if …else 判断 ? true : false 判断为true,返回?号后面的,判断为false ,返回: 号后面的 逻辑运算符 用…...

【开源】基于Vue.js的康复中心管理系统
项目编号: S 056 ,文末获取源码。 \color{red}{项目编号:S056,文末获取源码。} 项目编号:S056,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 普通用户模块2.2 护工模块2.3 管理员…...

抢先看|第二届世界直播电商大会邀您共话时代“新电商”
党的二十大报告指出,要加快发展数字经济,促进数字经济和实体经济深度融合。要深化国家数字经济创新发展试验区建设,打造一批具有国际竞争力的战略性新兴产业集群和数字产业集群。电子商务作为数字经济中规模最大、表现最活跃、发展势头最好的…...

火爆火爆!影响超250万读者,Python入门圣经全新升级!
人生苦短,快学Python! 什么?你没用过,也没开始学习,甚至没有认真了解过这门语言?那你一定这一秒就开始发力——下面让我们先简单看看 Python 有多火。权威编程语言排行榜 TIOBE,2022 和 2023 都…...
大数据学习(23)-hive on mapreduce对比hive on spark
&&大数据学习&& 🔥系列专栏: 👑哲学语录: 承认自己的无知,乃是开启智慧的大门 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言📝支持一下博主哦ᾑ…...
通过这个简单的技巧让我们的 JavaScript 代码变得异常快
通过这个简单的技巧让我们的 JavaScript 代码变得异常快 秘诀:了解JavaScript 虚拟机(VM)的内部工作原理。 首先,我们来谈谈像 V8 这样的JavaScript 虚拟机(VM)。可以把它想象成我们的操作的大脑 —— 它将我们简洁的代码变成计算机可以理解和执行的东…...

vue怎么实现国际化? vue-i18n 插件实现国际化,支持切换不同语言
依赖的文档开始 | Vue I18n 一、安装 npm install vue-i18n 如果在一个模块系统中使用它,你必须通过 Vue.use() 明确地安装 vue-i18n: import Vue from vue import VueI18n from vue-i18nVue.use(VueI18n)二、使用 在 src 下创建 lang 文件夹 1.准…...

rabbit MQ的延迟队列处理模型示例(基于SpringBoot延时插件实现)
rabbitMQ安装插件rabbitmq-delayed-message-exchange 交换机由此type 表示组件安装成功 生产者发送消息时设置延迟值 消息在交换机滞纳至指定延迟后,进入队列,被消费者消费。 组件注解类: package com.esint.configs;import org.springfra…...

虽不想承认,但这就是CSGO游戏搬砖行业的现状
CSGO搬砖日常出货更新 其实整个搬砖市场,现在已经变得乌烟瘴气,散发着“恶臭”。我个人非常鄙视那些虚有其表,大小通吃的做法,那些甚至连搬砖数据都看不懂的人,也出来吹嘘着“实力强大,经验丰富”。这个世界…...

想问问各位大佬,网络安全这个专业普通人学习会有前景吗?
网络安全是一个非常广泛的领域,涉及到许多不同的岗位。这些岗位包括安全服务、安全运维、渗透测试、web安全、安全开发和安全售前等。每个岗位都有自己的要求和特点,您可以根据自己的兴趣和能力来选择最适合您的岗位。 渗透测试/Web安全工程师主要负责模…...

uniapp IOS从打包到上架流程(详细简单) 原创
1.登入苹果开发者网站,打开App Store Connect 2.新App的创建 点击我的App可以进入App管理界面,在右上角点击➕新建App 即可创建新的App,如下图: 3.app基本信息填写 新建完App后,需要填写App的基本信息&…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...

C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...

Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...

Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...

Android写一个捕获全局异常的工具类
项目开发和实际运行过程中难免会遇到异常发生,系统提供了一个可以捕获全局异常的工具Uncaughtexceptionhandler,它是Thread的子类(就是package java.lang;里线程的Thread)。本文将利用它将设备信息、报错信息以及错误的发生时间都…...