java - 享元设计模式

标签 java design-patterns

我正在查看我在网上找到的享元模式的示例。

import java.util.Random;
import java.util.HashMap;

// A common interface for all players
interface Player
{
    public void assignWeapon(String weapon);
    public void mission();
}

// Terrorist must have weapon and mission
class Terrorist implements Player
{
    // Intrinsic Attribute
    private final String TASK;

    // Extrinsic Attribute
    private String weapon;

    public Terrorist()
    {
        TASK = "PLANT A BOMB";
    }
    public void assignWeapon(String weapon)
    {
        // Assign a weapon
        this.weapon = weapon;
    }
    public void mission()
    {
        //Work on the Mission
        System.out.println("Terrorist with weapon "
                        + weapon + "|" + " Task is " + TASK);
    }
}

// CounterTerrorist must have weapon and mission
class CounterTerrorist implements Player
{
    // Intrinsic Attribute
    private final String TASK;

    // Extrinsic Attribute
    private String weapon;

    public CounterTerrorist()
    {
        TASK = "DIFFUSE BOMB";
    }
    public void assignWeapon(String weapon)
    {
        this.weapon = weapon;
    }
    public void mission()
    {
        System.out.println("Counter Terrorist with weapon "
                        + weapon + "|" + " Task is " + TASK);
    }
}

// Claass used to get a playeer using HashMap (Returns
// an existing player if a player of given type exists.
// Else creates a new player and returns it.
class PlayerFactory
{
    /* HashMap stores the reference to the object
    of Terrorist(TS) or CounterTerrorist(CT). */
    private static HashMap <String, Player> hm =
                        new HashMap<String, Player>();

    // Method to get a player
    public static Player getPlayer(String type)
    {
        Player p = null;

        /* If an object for TS or CT has already been
        created simply return its reference */
        if (hm.containsKey(type))
                p = hm.get(type);
        else
        {
            /* create an object of TS/CT */
            switch(type)
            {
            case "Terrorist":
                System.out.println("Terrorist Created");
                p = new Terrorist();
                break;
            case "CounterTerrorist":
                System.out.println("Counter Terrorist Created");
                p = new CounterTerrorist();
                break;
            default :
                System.out.println("Unreachable code!");
            }

            // Once created insert it into the HashMap
            hm.put(type, p);
        }
        return p;
    }
}

// Driver class
public class CounterStrike
{
    // All player types and weopons (used by getRandPlayerType()
    // and getRandWeapon()
    private static String[] playerType =
                    {"Terrorist", "CounterTerrorist"};
    private static String[] weapons =
    {"AK-47", "Maverick", "Gut Knife", "Desert Eagle"};


    // Driver code
    public static void main(String args[])
    {
        /* Assume that we have a total of 10 players
        in the game. */
        for (int i = 0; i < 10; i++)
        {
            /* getPlayer() is called simply using the class
            name since the method is a static one */
            Player p = PlayerFactory.getPlayer(getRandPlayerType());

            /* Assign a weapon chosen randomly uniformly
            from the weapon array */
            p.assignWeapon(getRandWeapon());

            // Send this player on a mission
            p.mission();
        }
    }

    // Utility methods to get a random player type and
    // weapon
    public static String getRandPlayerType()
    {
        Random r = new Random();

        // Will return an integer between [0,2)
        int randInt = r.nextInt(playerType.length);

        // return the player stored at index 'randInt'
        return playerType[randInt];
    }
    public static String getRandWeapon()
    {
        Random r = new Random();

        // Will return an integer between [0,5)
        int randInt = r.nextInt(weapons.length);

        // Return the weapon stored at index 'randInt'
        return weapons[randInt];
    }
}

实现:实现了《反恐精英》游戏中恐怖分子和反恐怖分子的创建。所以我们有 2 类,一类是恐怖分子 (T),另一类是反恐分子 (CT)。每当玩家请求武器时,我们都会为他分配所请求的武器。在任务中,恐怖分子的任务是安放炸弹,而反恐怖分子则需要扩散炸弹。

我相信这个例子是错误的。在这个代码中对象保持不变,我们只是改变武器,如果一个新玩家进入游戏,每个人的武器都会改变。我的理解正确吗? 谁能给我提供一个 Fly Weight 的好例子。

最佳答案

你是对的,你的例子是错误的。 HashMap 中只有 2 个玩家(CT 和 Tero)。使用 HashMap 来存储 2 个必须播放的对象是非常简单的样板。

由于您只有两个游戏并且您正在更改它们的属性,因此您实际上正在更改所有玩家配置:)

我有modified a litle the example来表明这是错误的。我只是将播放器存储在一个数组中,然后重新打印它。

     System.out.println("reuse --------------------------");
    for(Player p : players){
        p.mission();
    }

这给了我 flowwing 输出:

    Terrorist Created
Terrorist with weapon Maverick| Task is PLANT A BOMB
Counter Terrorist Created
Counter Terrorist with weapon AK-47| Task is DIFFUSE BOMB
Terrorist with weapon AK-47| Task is PLANT A BOMB
Terrorist with weapon Maverick| Task is PLANT A BOMB
Terrorist with weapon Gut Knife| Task is PLANT A BOMB
Counter Terrorist with weapon Desert Eagle| Task is DIFFUSE BOMB
Terrorist with weapon Gut Knife| Task is PLANT A BOMB
Counter Terrorist with weapon Gut Knife| Task is DIFFUSE BOMB
Terrorist with weapon Maverick| Task is PLANT A BOMB
Terrorist with weapon Maverick| Task is PLANT A BOMB
reuse --------------------------
Terrorist with weapon Maverick| Task is PLANT A BOMB
Counter Terrorist with weapon Gut Knife| Task is DIFFUSE BOMB
Terrorist with weapon Maverick| Task is PLANT A BOMB
Terrorist with weapon Maverick| Task is PLANT A BOMB
Terrorist with weapon Maverick| Task is PLANT A BOMB
Counter Terrorist with weapon Gut Knife| Task is DIFFUSE BOMB
Terrorist with weapon Maverick| Task is PLANT A BOMB
Counter Terrorist with weapon Gut Knife| Task is DIFFUSE BOMB
Terrorist with weapon Maverick| Task is PLANT A BOMB
Terrorist with weapon Maverick| Task is PLANT A BOMB

您可以清楚地看到每个团队都使用相同的武器(最后选择的)。

如果您想要好的示例,请遵循您文章的引用文献;) :) :) 像 wikipedia

原则是重用已经创建的配置。

关于java - 享元设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51927070/

相关文章:

asp.net-mvc - Multi-Tenancy 和插件的 ASP.NET MVC 模式?

Java逻辑运算符(&&、||)短路机制

java - 通过 getClass().getResource() 加载文件

Java 访问说明符

design-patterns - Yegge 的原型(prototype)模式示例如何处理实例变量?

android - 从 AsyncTask 管理 ProgressDialog 的最佳方式

design-patterns - 如何限制使用 redis 的登录尝试?

java - Java中的重复检查

java - JasperReports 导出到 excel 自动大小列

java - 直觉与设计原则