我目前正在开发一个项目,我试图隐藏尽可能详细的层次结构。我想这样做是为了尽量减少用户需要了解的有关对象的信息量(并控制他们可以对对象的状态做些什么)。另外,我正在使用该模式来限制应用程序可以创建的对象类型,并将其限制为从工厂创建。
然而,我遇到的主要问题是我想要公开几种不同类型的接口。每个接口都有我认为不应该共享的附加功能,我希望将这些接口分开。最后,我不知道将来会出现什么样的新接口,但我想尝试为它们做好准备。
Weapon
:
public interface Weapon extends GameObject {
Number attack();
boolean addWeaponAttribute(WeaponAttribute attribute);
}
Firearm
:
public interface Firearm extends Weapon {
void reload(Number rounds);
}
我的问题是让工厂生产具有不同接口的对象的最佳方法是什么?这就是我所想的“最好的”:
这是我到目前为止所想的:
public static Firearm getFirearm(String firearmName) {
...
}
public static Weapon getWeapon(String weaponName) {
...
}
public class WeaponFactory {
public static Weapon getWeapon(String weaponName) {
...
}
}
public class FirearmFactory {
public static Firearm getFirearm(String firearmName) {
...
}
}
我愿意接受建议和改变。这是一个灵活的项目,所以我可以根据自己的需要进行更改(就项目的这一部分而言),以获得更好的结果。
另外 - 作为旁注,我不确定这个问题是否过于开放或不适用于SO。如果我在这里发布了一个错误,请告诉我,我会在其他地方提出问题。
答案 0 :(得分:2)
我可以建议的是尽可能简化界面并将其他不相关的方法移到别处。你可以考虑这样做:
public interface Weapon extends GameObject {
Number attack();
}
public interface Modifiable extends GameObject {
boolean addWeaponAttribute(WeaponAttribute attribute);
}
public class ActualWeapon implements Weapon, Modifiable {
...
}
然后,您可以创建不同的工厂来生成具体对象,如上所述:
public class WeaponFactory {
public static Weapon getWeapon(String weaponName) {
...
}
}
或
public class GenericFactory<T extends GameObject> {
public T createGameObject(Object... properties) {
...
}
}
public class WeaponFactory extends GenericFactory<ActualWeapon> {
public ActualWeapon createGameObject(Object... properties) {
...
}
}
我认为你不能在接口上添加静态方法。如果你愿意,我也不会推荐它。
答案 1 :(得分:1)
工厂工厂怎么样?每个工厂都会实施ifactory。 Ifacorty需要一个方法Instantiate(字符串类型)并返回你的子类武器实例。
答案 2 :(得分:1)
使用泛型,您可能只需要一个工厂方法,如:
public <T> T getObject(java.lang.Class<T> responseType, String name)
然后用户会致电:
Weapon weapon = factory.getObject(Weapon.class, "my weapon");
答案 3 :(得分:1)
可能只是使用工厂方法设计模式,如
interface GameObject {}
class WeaponAttribute {}
interface Weapon extends GameObject {
Number attack();
boolean addWeaponAttribute(WeaponAttribute attribute);
}
interface Firearm extends Weapon {
void reload(Number rounds);
}
class WeaponBaseClass implements Weapon {
WeaponBaseClass(WeaponName weaponName) {
this.weaponName=weaponName;
}
@Override public Number attack() {
return null;
}
@Override public boolean addWeaponAttribute(WeaponAttribute attribute) {
return false;
}
public String toString() {
return weaponName.toString();
}
final WeaponName weaponName;
}
class FirearmBaseClass extends WeaponBaseClass implements Firearm {
public FirearmBaseClass(WeaponName weaponName) {
super(weaponName);
}
@Override public void reload(Number rounds) {}
}
enum WeaponName {
knife, sword, colt45, glock19, glock19WithLaser;
}
class WeaponCreator {
Weapon create(WeaponName weaponName) {
switch (weaponName) {
case knife:
case sword:
return new WeaponBaseClass(weaponName);
case colt45:
case glock19:
return new FirearmBaseClass(weaponName);
default:
return new WeaponBaseClass(weaponName);
}
}
}
class FancyWeaponCreator extends WeaponCreator {
Weapon create(WeaponName weaponName) {
Weapon weapon = null;
switch (weaponName) {
case glock19WithLaser:
weapon = super.create(WeaponName.glock19);
// whatever it needs
return weapon;
default:
return new WeaponBaseClass(weaponName);
}
}
}
public class Main {
public static void main(String[] args) {
System.out.println(new WeaponCreator().create(WeaponName.knife));
System.out.println(new WeaponCreator().create(WeaponName.colt45));
System.out.println(new FancyWeaponCreator().create(WeaponName.glock19WithLaser));
}
}