1 策略模式

支付方式有:微信,支付宝,银联等。

定义策略接口

public interface PaymentStrategy {
  void pay(double amount) ;
}

实现不同支付方式

// 微信支付
@Component
public class WeiXinPayment implements PaymentStrategy {
  @Override
  public void pay(double amount) {
    // TODO
    System.out.printf("WeiXin pay %d%n ", amount) ;
  }
}
// 支付宝
@Component
public class AliPayment implements PaymentStrategy {
  @Override
  public void pay(double amount) {
    // TODO
    System.out.printf("Ali pay %d%n", amount) ;
  }
}
// 银联支付
@Component
public class BankPayment implements PaymentStrategy {
  @Override
  public void pay(double amount) {
    // TODO
    System.out.printf("Bank pay %d%n", amount) ;
  }
}

以上简单实现了3种支付方式,接下来具体使用

定义支付服务

@Service
public class PaymentService {
  private final Map<String, PaymentStrategy> paymentStrategies = new HashMap<>();


  public PaymentService(List<PaymentStrategy> strategies) {
    for (PaymentStrategy strategy : strategies) {
      paymentStrategies.put(strategy.getClass().getSimpleName(), strategy);
    }
  }


  public void processPayment(String strategyName, double amount) {
    PaymentStrategy strategy = paymentStrategies.get(strategyName) ;
    if (strategy != null) {
      strategy.pay(amount) ;
    } else {
      throw new IllegalArgumentException(String.format("不支持的支付方式: %s%n", strategyName)) ;
    }
  }
}

2 枚举方法

下面以订单状态管理为例进行讲解如何通过枚举来有效消除if else。

定义订单状态&行为

public enum OrderStatus {
  // 新建
  NEW {
    @Override
    public void process()
      // TODO
    }
  },
  // 支付中
  PAYING {
    @Override
    public void process()
      // TODO
    }
  },
  // 已支付
  PAID {
    @Override
    public void process() {
      // TODO
    }
  };
  // 已发货
  SHIPPED {
    @Override
    public void process() {
      // TODO
    }
  };
  // 处理订单状态的行为
  public abstract void process() ;
}

以上定义了4种订单状态,每种状态都有自己处理的行为。

定义处理订单状态

@Service
public class OrderService {
  public void processOrder(OrderStatus status) {
    status.handle() ;
  }
}

3 多态性

以下将以发送消息为例进行讲解

定义抽象接口

public interface Notification {
  void send(String message) ;
}

一个简单的消息发送接口。

定义具体实现类

@Component
public class EmailNotification implements Notification {
  @Override
  public void send(String message) {
    // 发送邮件
  }
}
@Component
public class SmsNotification implements Notification {
  @Override
  public void send(String message) {
    // 发送短信
  }
}

定义业务服务

@Service
public class NotificationService {
  private final List<Notification> notifications ;


  public NotificationService(List<Notification> notifications) {
    this.notifications = notifications ;
  }


  public void notifyAll(String message) {
    for (Notification notification : notifications) {
      notification.send(message) ;
    }
  }
}

通过Spring依赖注入,自动完成当前所有实现了Notification接口的bean

4 Lambda表达式&函数接口

下面以折扣功能为例进行讲解

@Service
public class DiscountService {
  private Map<String, Function<Double, Double>> discountStrategies = new HashMap<>();


  public DiscountService() {
    discountStrategies.put("VIP1", price -> price * 0.95) ;
    discountStrategies.put("VIP2", price -> price * 0.9) ;
    discountStrategies.put("VIP3", price -> price * 0.85) ;
    discountStrategies.put("VIP4", price -> price * 0.8) ;
    // ...
  }
  public double applyDiscount(String discountCode, double price) {
    return discountStrategies.getOrDefault(discountCode, Function.identity()).apply(price);
  }
}

上面通过Lambda表达式定义了不同VIP等级进行折扣处理。

5 命令模式

如下以文件操作为例进行讲解!!

定义命令接口&具体实现

public interface Command {
  void execute() ;
}
// 打开文件
@Component
public class OpenFileCommand implements Command {
  private FileSystemReceiver fileSystem ;


  public OpenFileCommand(FileSystemReceiver fs) {
    this.fileSystem = fs ;
  }


  @Override
  public void execute() {
    this.fileSystem.openFile() ;
  }
}
// 关闭文件
@Component
public class CloseFileCommand implements Command {
  private final FileSystemReceiver fileSystem;


  public CloseFileCommand(FileSystemReceiver fileSystem) {
    this.fileSystem = fileSystem;
  }


  @Override
  public void execute() {
    this.fileSystem.closeFile() ;
  }
}

定义文件操作接口

public interface FileSystemReceiver {
  void openFile() ;
  void closeFile() ;
}
@Service
public class UnixFileSystemReceiver implements FileSystemReceiver {
  @Override
  public void openFile() {
    // TODO
  }
  @Override
  public void closeFile() {
    // TODO
  }
}

定义文件调用程序

@Component
public class FileInvoker {
  private final Command command ;


  public FileInvoker(Command command) {
    this.command = command ;
  }
  public void execute() {
      this.command.execute() ;
  }
}

注:命令模式最大的一个缺点是,每个命令都的对应一个类。


最后说一句(求关注!别白嫖!)

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。

关注公众号:woniuxgg,在公众号中回复:笔记  就可以获得蜗牛为你精心准备的java实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!