设计模式:策略模式

策略模式能够将每一个策略封装到一个类中,这些类又具有共同接口,利用Java多态的特性就能够实现它们的相互替换。

例如我们去图书馆买书,会有很多种类的书,但是我们支付的时候都是去同一个地方支付的。因为收银员可以根据书本的条形码,执行不同的策略类计算书的价格。在这个时候,首先收银员要通过书的条形码知道是哪一本书,才能得到价格。策略模式也是如此,虽然策略类之间能够相互替换,但是收银员需要知道自己要调用哪一个策略类,才能知道金额。

案例
设计一个网上书店,该系统中所有的计算机类图书(ComputerBook)每本都有10%的折扣,所有的语言类图书(LanguageBook) 每本都有2元的折扣,小说类图书(NovelBook)每100元有10元的折扣。现使用策略模式来设计该系统,绘制类图并编程实现。

类图如下:
在这里插入图片描述

代码如下:
Book.java

public abstract class Book {
   abstract Double discount(Double price);
}

NovelBook.java

public class NovelBook extends Book {
   @Override
   Double discount(Double price) {
      return price-((int)(price/100))*10;
   }
}

ComputerBook.java

public class ComputerBook extends Book {
   @Override
   Double discount(Double price) {
      return 0.9*price;
   }
}

LanguageBook.java

public class LanguageBook extends Book {
   @Override
   Double discount(Double price) {
      return price-2;
   }
}

User.java

public class User {
   private Book book;
   public void setBook(Book book) {
      this.book = book;
   }
   public Double discount(Double price){
      return book.discount(price);
   }
}

测试代码:

public class Main {
   public static void main(String[] args) {
      User u=new User();
      u.setBook(new ComputerBook());
      System.out.println(u.discount(232.99));

      u.setBook(new LanguageBook());
      System.out.println(u.discount(232.99));

      u.setBook(new NovelBook());
      System.out.println(u.discount(232.99));
   }
}

测试结果:
在这里插入图片描述

总结
当添加一个新的策略类时,无需改动原来的代码,遵循OCP原则。不同的策略类之间能够很容易的相互替换。但是使用策略模式,客户必须知道所有策略类,才能自行决定要使用哪一个类。这就意味着客户端必须理解这些类之间有什么区别,才能根据不同场景选择正确的类。 同时,策略模式的每一个策略都要单独封装为类,和命令模式一样也是1:1的关系,因此也会造成类数目过多。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
策略模式是一种行为型设计模式,它允许在运行时动态地选择算法的行为,这些算法在同一接口中定义。在策略模式中,创建一个策略接口,然后定义多个实现该接口的具体策略类。接着,在使用策略的时候,需要根据不同的参数选择不同的策略类,然后调用其相应的方法。 在使用策略模式的时候,我们可以将不同的服务(service)接口封装成不同的策略类,在运行时根据参数选择不同的策略类,从而调用不同的服务接口。这可以使得代码更加灵活,易于扩展和维护。 下面是一个使用策略模式实现根据参数调用不同服务接口的示例代码: ```java // 策略接口 interface ServiceStrategy { void doService(); } // 具体策略类1 class Service1 implements ServiceStrategy { @Override public void doService() { System.out.println("调用服务1"); } } // 具体策略类2 class Service2 implements ServiceStrategy { @Override public void doService() { System.out.println("调用服务2"); } } // 上下文类 class ServiceContext { private ServiceStrategy strategy; public void setStrategy(ServiceStrategy strategy) { this.strategy = strategy; } public void executeService() { this.strategy.doService(); } } // 测试代码 public class Main { public static void main(String[] args) { ServiceContext context = new ServiceContext(); // 根据参数选择不同的策略类 String serviceType = "service1"; if (serviceType.equals("service1")) { context.setStrategy(new Service1()); } else if (serviceType.equals("service2")) { context.setStrategy(new Service2()); } // 调用服务 context.executeService(); } } ``` 在上面的示例代码中,我们定义了一个策略接口 `ServiceStrategy`,并实现了两个具体的策略类 `Service1` 和 `Service2`,分别对应不同的服务接口。然后,我们定义了一个上下文类 `ServiceContext`,用于执行服务。在上下文类中,我们使用了策略模式,根据参数选择不同的策略类,然后调用其相应的服务接口。最后,在测试代码中,我们演示了如何使用策略模式调用不同的服务接口。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值