代码之家  ›  专栏  ›  技术社区  ›  Punter Vicky

Java中的Flyweight模式

  •  0
  • Punter Vicky  · 技术社区  · 6 年前

    我遇到了 FlyWeight Pattern 在链接中描述。在提供的示例中,我相信只会创建2个player对象的实现。玩家不是每次都会创建一个变量吗?

    0 回复  |  直到 6 年前
        1
  •  1
  •   c0der    6 年前

    张贴的代码 Geeks For Geeks 只构造两个可变对象。
    PlayerFactory 返回一个播放器,它覆盖 weapon
    这很容易证明:

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Random;
    
    public class CounterStrike
    {
    
        private static String[] playerType = {"Terrorist", "CounterTerrorist"};
        private static String[] weapons = {"AK-47", "Maverick", "Gut Knife", "Desert Eagle"};
    
        public static void main(String args[])
        {
            List<Player> players = new ArrayList<>();
    
            System.out.println("-------  Construction of Players  ----------------");
            for (int i = 0; i < 10; i++)
            {
                Player p = PlayerFactory.getPlayer(getRandPlayerType());
                p.assignWeapon(getRandWeapon());
                p.mission();
                players.add(p);
            }
    
            System.out.println("-------  Printout all players ----------------");
            for(Player p : players) {
                p.mission();
            }
        }
    
        public static String getRandPlayerType()
        {
            // Will return 0 or 1
            int randInt =  new Random().nextInt(playerType.length);
            return playerType[randInt];
        }
    
        public static String getRandWeapon()
        {
            // Will return an integer between 0 inclusive and 5 exclusive
            int randInt = new Random().nextInt(weapons.length);
            return weapons[randInt];
        }
    }
    
    interface Player
    {
        void assignWeapon(String weapon);
        void mission();
    }
    
    class Terrorist implements Player
    {
        private final String TASK;
        private String weapon;
    
        public Terrorist()
        {
            TASK = "PLANT A BOMB";
        }
    
        @Override
        public void assignWeapon(String weapon)
        {
            this.weapon = weapon;
        }
    
        @Override
        public void mission()
        {
            System.out.println("Terrorist with weapon " + weapon + "|" + " Task is " + TASK);
        }
    }
    
    class CounterTerrorist implements Player
    {
        private final String TASK;
        private String weapon;
    
        public CounterTerrorist()
        {
            TASK = "DIFFUSE BOMB";
        }
        @Override
        public void assignWeapon(String weapon)
        {
            this.weapon = weapon;
        }
        @Override
        public void mission()
        {
            System.out.println("Counter Terrorist with weapon "+ weapon + "|" + " Task is " + TASK);
        }
    }
    
    class PlayerFactory
    {
        private static HashMap <String, Player> hm =  new HashMap<>();
    
        public static Player getPlayer(String type)
        {
            Player p = null;
    
            if (hm.containsKey(type)) {
                p = hm.get(type);
            } else
            {
                switch(type)
                {
                case "Terrorist":
                    p = new Terrorist();
                    break;
                case "CounterTerrorist":
                    p = new CounterTerrorist();
                    break;
                default :
                    System.out.println("Unreachable code!");
                }
    
                hm.put(type, p);
            }
            return p;
        }
    }
    

    输出显示所有恐怖分子都拥有最后使用的武器(Maverick),所有CT都是AK-47:


    编辑:
    从我看到的 other examples 外部属性需要由工厂管理。
    public class CounterStrike
    {
        //better use enums
        private static String[] playerType = {"Terrorist", "CounterTerrorist"};
        private static String[] weapons = {"AK-47", "Maverick", "Gut Knife", "Desert Eagle"};
    
        public static void main(String args[])
        {
            List<Player> players = new ArrayList<>();
    
            System.out.println("-------  Construction of Players  ----------------");
            for (int i = 0; i < 10; i++)
            {
                String type = getRandPlayerType();
                Player p = type.equals(playerType[0]) ?  PlayerFactory.getTerrorist(getRandWeapon()) :
                    PlayerFactory.getCoubterTerrorist(getRandWeapon()) ;
                p.mission();
                players.add(p);
            }
    
            System.out.println("-------  Printout all players ----------------");
            for(Player p : players) {
                p.mission();
            }
        }
    
        public static String getRandPlayerType()
        {
            // Will return 0 or 1
            int randInt =  new Random().nextInt(playerType.length);
            return playerType[randInt];
        }
    
        public static String getRandWeapon()
        {
            // Will return an integer between 0 inclusive and 5 exclusive
            int randInt = new Random().nextInt(weapons.length);
            return weapons[randInt];
        }
    }
    
    class PlayerFactory
    {
        private static HashMap <String, Player> terrorists =  new HashMap<>();
        private static HashMap <String, Player> cTerrorists =  new HashMap<>();
    
        public static Player getTerrorist(String weapon)
        {
            Player p = null;
    
            if (terrorists.containsKey(weapon)) {
                p = terrorists.get(weapon);
            } else{
                p = new Terrorist(weapon);
            }
            terrorists.put(weapon, p);
            return p;
        }
    
        public static Player getCoubterTerrorist(String weapon)
        {
            Player p = null;
    
            if (cTerrorists.containsKey(weapon)) {
                p = cTerrorists.get(weapon);
            } else{
                p = new CounterTerrorist(weapon);
            }
            cTerrorists.put(weapon, p);
            return p;
        }
    }
    interface Player
    {
        void mission();
    }
    
    class Terrorist implements Player
    {
        private final String TASK;
        private String weapon;
    
        public Terrorist(String weapon)
        {
            this.weapon = weapon;
            TASK = "PLANT A BOMB";
        }
    
        @Override
        public void mission()
        {
            System.out.println("Terrorist with weapon " + weapon + "|" + " Task is " + TASK);
        }
    }
    
    class CounterTerrorist implements Player
    {
        private final String TASK;
        private String weapon;
    
        public CounterTerrorist(String weapon)
        {
            this.weapon = weapon;
            TASK = "DIFFUSE BOMB";
        }
    
        @Override
        public void mission()
        {
            System.out.println("Counter Terrorist with weapon "+ weapon + "|" + " Task is " + TASK);
        }
    }
    

    我们可以通过使用枚举来改进实现,并使播放器类型成为一个内在属性,而不是一个类:

    public class CounterStrike
    {
        public enum PlayerType{
    
            TERRORIST("PLANT A BOMB"), COUNTER_TERRORIST("DIFFUSE BOMB");
    
            private final String task;
    
            PlayerType(String task){
                this.task = task;
            }
    
            String getTask(){ return task;  }
        }
    
        public enum Weapon {
    
            AK47("AK-47"), MAVERICK("Maverick"), GUT_KNIFE("Gut Knife"), DESERT_EAGLE("Desert Eagle");
    
            private final String name;
    
            Weapon(String name) {   this.name = name;   }
    
            String getName(){ return name;  }
    
            @Override
            public String toString() { return name; }
        }
    
        public static void main(String args[])
        {
            List<Player> players = new ArrayList<>();
    
            System.out.println("-------  Construction of Players  ----------------");
            for (int i = 0; i < 10; i++)
            {
                Player p = PlayerFactory.getPlayer(getRandPlayerType(), getRandWeapon()) ;
                players.add(p);
                System.out.println("Created: "+ p);
            }
    
            System.out.println("-------  Printout all players ----------------");
            for(Player p : players) {   System.out.println(p);  }
        }
    
        public static PlayerType getRandPlayerType()
        {
            int randInt =  new Random().nextInt(PlayerType.values().length);
            return PlayerType.values()[randInt];
        }
    
        public static Weapon getRandWeapon()
        {
            int randInt =  new Random().nextInt(Weapon.values().length);
            return Weapon.values()[randInt];
        }
    }
    
    class PlayerFactory
    {
        private static HashMap <Weapon, Player> terrorists =  new HashMap<>();
        private static HashMap <Weapon, Player> cTerrorists =  new HashMap<>();
    
        static Player getPlayer(PlayerType type, Weapon weapon) {
    
            return type == PlayerType.TERRORIST ? getTerrorist(weapon) : getCounterTerrorist(weapon);
        }
    
        private static Player getTerrorist(Weapon weapon)
        {
            Player p = null;
    
            if (terrorists.containsKey(weapon)) {
                p = terrorists.get(weapon);
            } else{
                p = new Player(PlayerType.TERRORIST, weapon);
            }
            terrorists.put(weapon, p);
            return p;
        }
    
        private static Player getCounterTerrorist(Weapon weapon)
        {
            Player p = null;
    
            if (cTerrorists.containsKey(weapon)) {
                p = cTerrorists.get(weapon);
            } else{
                p = new Player(PlayerType.COUNTER_TERRORIST, weapon);
            }
            cTerrorists.put(weapon, p);
            return p;
        }
    }
    
    class Player
    {
        private final Weapon weapon;
        private final PlayerType type;
    
        Player(PlayerType type, Weapon weapon) {
            this.type = type;
            this.weapon = weapon;
        }
    
        Weapon getWeapon() { return weapon; }
    
        PlayerType getType() {return type; }
    
        String getTask() {  return type.getTask(); }
    
        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder(type == PlayerType.TERRORIST ? "Terrorist" : "Counter Terrorist" );
            sb.append(" armed with ").append(weapon).append(". Task: ").append(type.getTask());
            return sb.toString();
        }
    }
    
        2
  •  1
  •   Gilbert Le Blanc    6 年前

    Class Diagram

    如果我理解正确,游戏会创建一个 Terrorist ,的一个实例 CounterTerrorist ,和 n 实例 Player 由 PlayerFactory .

    恐怖分子 和 反恐 实施 接口。

    每个 玩家 由创建的实例 播放器工厂 恐怖分子 或 反恐 例如,取决于玩家在哪一边。因为有一个 玩家

    这个 CounterStrike 类管理 Map 由 播放器工厂 .

    这个简单的现实世界的例子最小化了如果只是 玩家 实例。每个 玩家 例如,必须保存恐怖分子和反恐分子的信息。

    通过创建 恐怖分子 反恐 ,并与共享这些实例 玩家 实例中,游戏场的总存储量减少。

    游戏代码可能也更容易调试和管理。

    Java代码可以在 Geeks For Geeks .