-1

我有一堂课Player,需要Location上课。每个位置类都 extends Location,它有一个get()返回静态实例的方法。

如果字符有一个引用位置扩展类名称的字符串,我如何获取实例?

特点:

public class Player {
    public static Location getLocation() {
        try {
            //return location
        } catch (Exception ex) {
            Logger.getLogger(Player.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }
}

地点:

public class Location{
    protected static Location singleton;
    public static Location get() {
        return null;
    }

位置类:

public class Finleydale extends Location{
    public static Location get() {
        if (Finleydale.singleton == null) {
            Finleydale.singleton = new Finleydale();
        }
        return singleton;
    }
}

我有多个附加地址信息,并且我在位置类中有单例,所以所有附加地址信息都有它;并且单例是静态的,因为该位置只有一个版本。有人可以帮我弄这个吗?

4

3 回答 3

0

您在基类中声明静态字段的方式意味着您在整个程序中只有一个引用。如果您有多个子类,并且每个子类都分配给它,那么每个子类都分配给基类中的相同(静态)字段。Location我认为您希望每个子类中都有一个单独的单例。

如果您想通过键(例如字符串值)查找特定位置,那么我认为 Singleton 模式并不是您正在寻找的。我会创建一个“位置注册表”类,如下所示:

public class LocationRegistry
    {
    private static final Map<String, Location> registry;
    static
        {
        final Map<String, Location> _registry = new HashMap<>();
        _registry.put("Finleydale", new Finleydale());
        // ...
        registry = Collections.unmodifiablemap(_registry);
        }

    public static Location getLocation(final String id)
        {
        return registry.get(id);
        }
    }

一些注意事项:

  • 您仍然可以使用 Singleton 模式来填充注册表
  • 如您的问题所示,经典的单例模式不是线程安全的。如果不是不可能的话,一个没有不必要锁定的正确线程安全版本是非常棘手的。一个static final字段很好地解决了这个问题。
  • 没有必要让注册表显式引用每个 Location 子类。您可以让每个位置注册自己。唯一的技巧是有一种机制可以加载位置,以便它们可以注册自己。
  • 子类实际上适合这种用途吗?不同的位置是否有不同的行为或只是不同的数据(即名称)?如果是后者,那么我将只使用一个 Location 类和一个工厂(例如上面的静态初始化程序)来创建每个位置。
于 2013-03-23T03:25:14.627 回答
0

关于您的对象模型的某些内容似乎是错误的。为什么没有一个Locatable带有getLocation()方法的接口,接口的实现者可以返回它们各自的位置。单例Location在概念上似乎是错误的。

interface Locatable { 
   Location getLocation();
}

class FinleyLand implements Locatable { 
    @Override
    Location getLocation() { 
       //whatever it takes to get you there...
    }     
}
于 2013-03-23T03:33:44.663 回答
0

我拿走了 get() 函数的静态修饰符并更改了 Player 类,如图所示。
你们其他人,你们的意见很棒。

    String locationS; //Class name
    public static Location getLocation() {
        return ((Location) Class.forName(locationS).newInstance()).get();
    }
于 2013-03-23T16:14:56.680 回答