1.模式定义:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式的变化独立于算法的使用者。

如下,游戏初期只有两种僵尸,除了外观,其它的都一样
image.png

  1. abstract class AbstractZombie{
  2. public abstract void display();
  3. public void attack(){
  4. System.out.println("咬.");
  5. }
  6. public void move(){
  7. System.out.println("一步一步走.");
  8. }
  9. }
  10. class NormalZombie extends AbstractZombie{
  11. public void display(){
  12. System.out.println("我是普通僵尸.");
  13. }
  14. }
  15. class FlagZombie extends AbstractZombie{
  16. public void display(){
  17. System.out.println("我是旗手僵尸.");
  18. }
  19. }
  20. public class StrategyTest {
  21. public static void main(String[] args) {
  22. NormalZombie normalZombie = new NormalZombie();
  23. normalZombie.display();
  24. normalZombie.move();
  25. normalZombie.attack();
  26. FlagZombie flagZombie = new FlagZombie();
  27. flagZombie.display();
  28. flagZombie.move();
  29. flagZombie.attack();
  30. }
  31. }

随着游戏的升级,引入了更多的僵尸,也就是移动方式和攻击方式都更加多了,未来变化也不可知,而且相互之间的攻击方式也有可能随着等级的变化而发生变化,对于移动方式和攻击方式就都需要进行抽象了,让子类去实现不同的移动方式和攻击方式。
image.png

  1. interface MoveAble{
  2. void move();
  3. }
  4. interface AttackAble{
  5. void attack();
  6. }
  7. class StepByStep implements MoveAble{
  8. @Override
  9. public void move() {
  10. System.out.println("一步一步的移动.");
  11. }
  12. }
  13. class BiteAttack implements AttackAble{
  14. @Override
  15. public void attack() {
  16. System.out.println("咬.");
  17. }
  18. }
  19. class HitAttack implements AttackAble{
  20. @Override
  21. public void attack() {
  22. System.out.println("打.");
  23. }
  24. }
  25. abstract class Zombie{
  26. public MoveAble moveAble;
  27. public AttackAble attackAble;
  28. public Zombie(MoveAble moveAble, AttackAble attackAble) {
  29. this.moveAble = moveAble;
  30. this.attackAble = attackAble;
  31. }
  32. abstract public void display();
  33. abstract void move();
  34. abstract void attack();
  35. }
  36. class NormalZombie extends Zombie{
  37. public NormalZombie() {
  38. super(new StepByStep(),new BiteAttack());
  39. }
  40. @Override
  41. public void display() {
  42. System.out.println("我是普通僵尸.");
  43. }
  44. @Override
  45. void move() {
  46. moveAble.move();
  47. }
  48. @Override
  49. void attack() {
  50. attackAble.attack();
  51. }
  52. }
  53. class FlagZombie extends Zombie{
  54. public FlagZombie() {
  55. super(new StepByStep(), new BiteAttack());
  56. }
  57. @Override
  58. public void display() {
  59. System.out.println("我是旗手僵尸.");
  60. }
  61. @Override
  62. void move() {
  63. moveAble.move();
  64. }
  65. @Override
  66. void attack() {
  67. attackAble.attack();
  68. }
  69. }
  70. public class StrategyTest {
  71. public static void main(String[] args) {
  72. NormalZombie normalZombie = new NormalZombie();
  73. normalZombie.display();
  74. normalZombie.move();
  75. normalZombie.attack();
  76. System.out.println("普通僵尸升级了...");
  77. normalZombie.attackAble = new HitAttack();
  78. normalZombie.attack();
  79. }
  80. }

image.png

应用场景
1.当你有很多类似的类,但它们执行某些行为的方式不同时,请使用此策略。
2.使用该模式将类的业务逻辑与算法的实现细节隔离开来,这些算法在逻辑上下文中可能不那么重要。
3.当你的类具有大量的条件运算符,并且在同一算法的不同变体之间切换时,请使用此模式。

优点:
1.可以将算法的实现细节与使用它的代码隔离开来。
2.符合开闭原则

Spring&JDK源码中的应用
1java.util.Comparator
2org.springframework.beans.factory.support.InstantiationStrategy