Polymorphism vs Strategy pattern

后端 未结 10 922
陌清茗
陌清茗 2021-01-30 10:12

What is the difference between the Strategy pattern and Polymorphism in Java?

I\'m confused that whatever is achieved via Strategy Pattern is

10条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-01-30 11:05

    For me, the link from CKing post and the example in Wikipedia are clear enough, but I'll try to give you a new example. As they said, Strategy Pattern is mostly a way to change the behaviour of an algorithm at runtime. Of course you can achieve this in many different ways (such as holding a value and using switch-case, but it wouldn't be as nice as Strategy Pattern).

    Let's say you're developing a turn-based strategy game with two kind of Units: Infantry and Tank (subclasses of Unit). Your terrain could be Plains, Railroad or Forests.

    class Unit{
        MovementStrategy ms;      
        final int baseMovement;
        int x,y;
    
        public Unit(int baseMovement){
            this.baseMovement = baseMovement;
        }
    
        abstract void fire();
    
        void moveForward(){
            x = x + ms.getHexagonsToMove(baseMovement);
        }
    
        void setMovementStrategy(MovementStrategy ms){
            this.ms = ms;
        }
    }
    

    Any Unit subclass must implement fire() method because it's going to be completely different for them (Tank shots heavy long-distance round and Infantry shot several short distance light bullets). In this example we use normal polymorphism/inheritance since fire() method will be really different for any unit, and it won't change during the game.

    class Infantry extends Unit{
        public Infantry(){
            super(2);
        }
    
        void fire(){
            //whatever
        }
    }
    
    class Tank extends Unit{
        public Tank(){
            super(5);
        }
    
        void fire(){
            //whatever
        }
    }
    

    Units also are able to move, and have a field baseMovement that holds the number of hexagons it can walk. We're developing a strategy game, not a real world simulation, so we don't care how they move, we just want to add a value to their coordinates (in my example I only use X coordinate in order to get a simpler code). If all the terrain was the same, we wouldn't need any Strategy object... but we need to change the behaviour of move() method at runtime!

    So, we implement a different MovementStrategy class for each of our kinds of Terrain, and we program our game to trigger a setMovementStrategy() to any unit that move on each hexagon. And we don't even need to write anything else in our Unit subclasses.

    interface MovementStrategy{
        public int getHexagonsToMove(int base);
    }
    
    class PlainMovementStrategy implements MovementStrategy{
        public int getHexagonsToMove(int base){
            return base;
        }
    }
    
    class RailroadMovementStrategy implements MovementStrategy{
        public int getHexagonsToMove(int base){
            return base*3;
        }
    }
    
    class ForestMovementStrategy implements MovementStrategy{
        public int getHexagonsToMove(int base){
            return (int)(base/2);
        }
    }   
    

    Now, when any Unit move inside a Forest, we call

    unit.setMovementStrategy(new ForestMovementStrategy());
    

    And as soon it goes to a Plain, we do:

    unit.setMovementStrategy(new PlainMovementStrategy());
    

    Now we're able to change how far away our units move depending on the Terrain, and we don't need to rewrite in any of the subclasses.

    I hope this helps you a better understanding of the difference.

提交回复
热议问题