网约车系统优化:使用【策略模式】、【状态模式】、【观察者模式】设计模式重新设计网约车系统代码 优化建议二

接上一篇:Java并发编程:使用设计模式重新设计的网约车系统代码 优化建议一

目录

  • 1、策略模式(Strategy Pattern):处理不同类型的订单
  • 2、状态模式(State Pattern):根据不同的条件来分配司机
  • 3、观察者模式(Observer Pattern):处理大量的订单和司机
  • 4、反模式代码对比
  • 5、网约车业务需求与代码示例
(使用设计模式重新设计网约车系统代码 优化建议二)

上一篇末尾提到了,考虑使用【策略模式】、【状态模式】、【观察者模式】设计模式进一步优化网约车系统代码:

根据具体的项目需求,可能还需要考虑使用其他的设计模式来进一步优化设计。例如,如果需要处理多种不同类型的订单,可能需要使用策略模式(Strategy Pattern)来将处理逻辑封装在独立的策略类中。同样,如果需要根据不同的条件来分配司机,可能需要使用状态模式(State Pattern)。如果处理大量的订单和司机,可能需要考虑使用观察者模式(Observer Pattern)来实现司机和订单之间的解耦。

原文链接:Java并发编程:使用设计模式重新设计的网约车系统代码 优化建议一

以下是给出一些设计模式的示例代码,以帮助进一步优化网约车代码逻辑。

1、策略模式(Strategy Pattern):处理不同类型的订单

如果你需要处理不同类型的订单,可以使用策略模式将处理逻辑封装在独立的策略类中。例如,你可以创建一个订单处理策略接口,然后为不同类型的订单创建不同的实现。

public interface OrderProcessingStrategy {
    void processOrder(Order order);
}

public class OrderProcessingStrategyA implements OrderProcessingStrategy {
    @Override
    public void processOrder(Order order) {
        // 处理A类型订单的逻辑代码
        // ...
    }
}

public class OrderProcessingStrategyB implements OrderProcessingStrategy {
    @Override
    public void processOrder(Order order) {
        // 处理B类型订单的逻辑代码
        // ...
    }
}

然后在你的订单处理器中使用这个策略接口:

public class OrderProcessor {
    private OrderProcessingStrategy strategy;

    public OrderProcessor(OrderProcessingStrategy strategy) {
        this.strategy = strategy;
    }

    public void processOrder(Order order) {
        strategy.processOrder(order);
    }
}

2、状态模式(State Pattern):根据不同的条件来分配司机

如果你需要根据不同的条件来分配司机,可以使用状态模式。例如,你可以创建一个司机分配状态接口,然后为每种状态创建一个实现类。

public interface DriverAssignmentState {
    void assignDriver(Order order, Driver driver);
}

public class DriverAssignmentStateA implements DriverAssignmentState {
    @Override
    public void assignDriver(Order order, Driver driver) {
        // 根据某种条件分配司机的逻辑代码
        // ...
    }
}

public class DriverAssignmentStateB implements DriverAssignmentState {
    @Override
    public void assignDriver(Order order, Driver driver) {
        // 根据另一种条件分配司机的逻辑代码
        // ...
    }
}

然后在你的司机分配器中使用这个状态接口:

public class DriverAssigner {
    private DriverAssignmentState state;

    public DriverAssigner(DriverAssignmentState state) {
        this.state = state;
    }

    public void assignDriverToOrder(Order order, Driver driver) {
        state.assignDriver(order, driver);
    }
}

3、观察者模式(Observer Pattern):处理大量的订单和司机

如果需要处理大量的订单和司机,可能需要考虑使用观察者模式实现司机和订单之间的解耦。例如,可以创建一个订单观察者接口,然后让司机实现这个接口。当订单的状态发生改变时,会通知所有的观察者(司机)。

public interface OrderObserver {
    void update(Order order);
}

public class Driver implements OrderObserver {
    @Override
    public void update(Order order) {
        // 当订单状态发生改变时,司机会收到通知并执行相应的操作
        // ...
    }
}

然后在订单类中使用这个观察者接口:

public class Order {
    private List<OrderObserver> observers = new ArrayList<>();
    private Status status; // 订单的状态,可以是一个枚举类型或一个类。

    public void addObserver(OrderObserver observer) {
        observers.add(observer);
    }

    public void removeObserver(OrderObserver observer) {
        observers.remove(observer);
    }

    public void changeStatus(Status newStatus) {
        status = newStatus;
        notifyObservers(); // 通知所有观察者订单状态发生了改变。
    }

    private void notifyObservers() {
        for (OrderObserver observer : observers) {
            observer.update(this); // 通知观察者订单的状态发生了改变。
        }
    }   
    // ... 继续处理逻辑代码. 司机可以注册成为订单的观察者,当订单状态发生改变时,会自动收到通知。
    // 例如,当订单状态变为“已完成”时,司机可以收到通知并执行相应的操作。这样,司机和订单之间的耦合就被解耦了。

4、反模式代码对比

接下来,让我们来看一段反模式代码。假设我们有一个订单管理器类,它负责管理订单和司机之间的关系,并且当订单状态改变时通知司机。但是,这个代码没有使用观察者模式,而是使用了直接依赖的方式:

public class OrderManager {
    private List<Order> orders;
    private List<Driver> drivers;

    public OrderManager(List<Order> orders, List<Driver> drivers) {
        this.orders = orders;
        this.drivers = drivers;
    }

    public void changeOrderStatus(Order order, String newStatus) {
        order.setStatus(newStatus);
        // 通知所有司机
        for (Driver driver : drivers) {
            if (driver.getAvailableOrders().contains(order)) {
                driver.updateOrderStatus(order);
            }
        }
    }
}

在这段代码中,订单管理器直接依赖司机列表,并在订单状态改变时手动通知每个司机。这种方式存在以下问题:

  1. 紧耦合:订单管理器依赖于司机列表,使得它们之间的依赖关系紧密耦合在一起。如果司机的实现发生改变,订单管理器的代码也需要相应地进行修改。
  2. 可维护性差:当订单状态改变时,订单管理器需要遍历整个司机列表,检查每个司机是否有可用的订单。如果司机数量很大,这将会是一个性能瓶颈。
  3. 缺乏灵活性:如果未来需要添加更多的观察者(例如,需要通知订单观察者或者物流服务),代码将需要进行大量的修改。

为了避免这些问题,我们可以使用观察者模式来重构上述代码。下面是使用观察者模式的代码示例:

public interface OrderObserver {
    void update(Order order);
}

public interface OrderSubject {
    void addObserver(OrderObserver observer);
    void removeObserver(OrderObserver observer);
    void notifyObservers(Order order);
}

public class Order implements OrderSubject {
    private List<OrderObserver> observers;
    private String status;

    public Order(String status) {
        this.status = status;
        this.observers = new ArrayList<>();
    }

    public void addObserver(OrderObserver observer) {
        observers.add(observer);
    }

    public void removeObserver(OrderObserver observer) {
        observers.remove(observer);
    }

    public void changeStatus(String newStatus) {
        status = newStatus;
        notifyObservers(this);
    }

    public void notifyObservers(Order order) {
        observers.forEach(observer -> observer.update(order));
    }
}

public class Driver implements OrderObserver {
    private List<Order> acceptedOrders;

    public Driver() {
        this.acceptedOrders = new ArrayList<>();
    }

    public void addOrder(Order order) {
        acceptedOrders.add(order);
    }

    public void updateOrderStatus(Order order) {
        // 根据订单状态更新司机状态...
    }

    @Override
    public void update(Order order) {
        // 当订单状态改变时更新司机状态...
    }
}

在这段代码中,订单实现了OrderSubject接口,而司机实现了OrderObserver接口。当订单状态改变时,notifyObservers方法会被调用,从而自动通知所有观察者(即司机)。这种方式具有以下优点:

  1. 解耦:通过使用观察者模式,订单和司机的依赖关系被解除。司机只需要关注订单状态的变化,而不需要了解其他订单的详细信息。这使得代码更加简洁和易于维护。
  2. 灵活性:如果未来需要添加更多的观察者(例如,需要通知订单观察者或者物流服务),只需要实现OrderObserver接口并注册到订单对象中即可。不需要对原有的代码进行修改。
  3. 自动通知:当订单状态改变时,观察者会自动收到通知并更新它们的状态,无需手动调用。这提高了系统的自动化程度,减少了人为错误的可能性。

5、网约车业务需求与代码示例

当用户通过网约车平台发出约车请求时,平台会创建一个订单对象。这个订单对象包含用户请求的信息,例如出发地、目的地、乘车时间等。同时,平台会将这个订单发布给所有在线的司机。

司机可以在平台上看到发布的订单,可以选择接单或者不接单。如果司机选择接单,他会订阅这个订单,成为该订单的观察者。在这个例子中,司机类实现了订单观察者接口,因此可以接收订单状态变化的通知。

当订单的状态发生改变时,比如订单被接受或被取消,平台会通知所有订阅了这个订单的司机。这里使用了观察者模式,订单对象作为主题,司机对象作为观察者。当订单状态改变时,所有订阅了该订单的司机都会自动收到通知。

收到通知后,司机根据订单的状态更新自己的状态。例如,如果订单被接受,司机就会开始规划行车路线,准备接送用户;如果订单被取消,司机就会取消相应的行程安排。

同时,这段代码还支持司机观察多个订单。每个司机可以订阅多个订单,当这些订单的状态发生改变时,司机都会收到相应的通知。

通过这种方式,订单和司机之间实现了解耦,订单的状态改变会自动通知司机,避免了直接依赖的方式带来的问题。同时,这种方式也提高了系统的自动化程度,减少了人为错误的可能性。

好的,以下是一个简单的Java代码示例,实现了上述的业务逻辑:

// 订单观察者接口
interface OrderObserver {
    void update(Order order);
}

// 订单主题接口
interface OrderSubject {
    void addObserver(OrderObserver observer);
    void removeObserver(OrderObserver observer);
    void notifyObservers(Order order);
}

// 订单类,实现了订单主题接口
class Order implements OrderSubject {
    private List<OrderObserver> observers;
    private String status;

    public Order(String status) {
        this.status = status;
        this.observers = new ArrayList<>();
    }

    public void addObserver(OrderObserver observer) {
        observers.add(observer);
    }

    public void removeObserver(OrderObserver observer) {
        observers.remove(observer);
    }

    public void changeStatus(String newStatus) {
        status = newStatus;
        notifyObservers(this);
    }

    public void notifyObservers(Order order) {
        observers.forEach(observer -> observer.update(order));
    }
}

// 司机类,实现了订单观察者接口
class Driver implements OrderObserver {
    private List<Order> acceptedOrders;

    public Driver() {
        this.acceptedOrders = new ArrayList<>();
    }

    public void addOrder(Order order) {
        acceptedOrders.add(order);
    }

    @Override
    public void update(Order order) {
        // 根据订单状态更新司机状态,这里仅作示例,实际业务逻辑需要根据具体需求实现
        if (order.getStatus().equals("accepted")) {
            // 开始规划行程路线等操作
            System.out.println("Driver is planning the route for the accepted order.");
        } else if (order.getStatus().equals("cancelled")) {
            // 取消相应的行程安排等操作
            System.out.println("Driver is canceling the route for the cancelled order.");
        }
    }
}

使用示例:

  1. 创建一个订单对象:
Order order = new Order("requested");
  1. 创建一个司机对象:
Driver driver = new Driver();
  1. 司机订阅订单,成为观察者:
driver.addOrder(order); // 司机订阅订单,成为观察者
  1. 当订单状态改变时,调用changeStatus方法更新状态,并自动通知所有订阅的司机:
order.changeStatus("accepted"); // 订单被接受,更新状态并通知观察者

在上述代码中,当订单的状态被改变时(例如被接受或被取消),Order类会调用notifyObservers方法,自动通知所有订阅了该订单的司机。司机在收到通知后,会根据订单的状态更新自己的状态,例如开始规划行程路线或取消行程安排等操作。

...全文
298 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

168,446

社区成员

发帖
与我相关
我的任务
社区描述
一个人可以走的很快,一群人才能走的更远! 加我微信群一起交流讨论学习! 共创美好社区!
社区管理员
  • 呆呆敲代码的小Y
  • 芝麻粒儿
  • 布小禅
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

社区公告:

【社区核心】学习优先,其他靠边!

社区每日打卡贴,学习有福利,奖励不断!

【游戏开发爱好者社区】本周重磅推出【每日打卡】活动

🎁 新玩法,奖励升级!

游戏开发爱好者社区:https://bbs.csdn.net/forums/unitygame

社区中心思想:今天你学到了什么?

⭐️ 活动要求:

  1. 每日 在 社区打卡贴 进行发帖打卡,提交任务
  2. 在社区 坚持 5 天打卡 ,将参与到抽奖名单中,这很重要!
  3. 打卡满七天的周末时 社区积分排行榜第前三 的小伙伴可任选一本以下书籍,其余的抽奖处理~
  4. 参加抽奖请先 添加打卡抽奖群,否则无效,加群请添加微信:ZAY1422761991

本周抽奖池技术书籍分别各3本,一共6本

【社区积分规则】

  • 在社区「发帖」得20积分
  • 内容被管理员「加精」得50积分
  • 点赞他人内容得2积分
  • 评论内容得5积分

 

试试用AI创作助手写篇文章吧