暴露多个接口的技术(通过静态创建方法)

时间:2011-08-30 00:20:03

标签: java design-patterns factory-pattern

我目前正在开发一个项目,我试图隐藏尽可能详细的层次结构。我想这样做是为了尽量减少用户需要了解的有关对象的信息量(并控制他们可以对对象的状态做些什么)。另外,我正在使用该模式来限制应用程序可以创建的对象类型,并将其限制为从工厂创建。

然而,我遇到的主要问题是我想要公开几种不同类型的接口。每个接口都有我认为不应该共享的附加功能,我希望将这些接口分开。最后,我不知道将来会出现什么样的新接口,但我想尝试为它们做好准备。

Weapon

public interface Weapon extends GameObject {
    Number attack();

    boolean addWeaponAttribute(WeaponAttribute attribute);
}

Firearm

public interface Firearm extends Weapon {
    void reload(Number rounds);
}

我的问题是让工厂生产具有不同接口的对象的最佳方法是什么?这就是我所想的“最好的”:

  1. 对用户最清楚(显而易见的是他们要求的内容以及他们要回来的内容)
  2. 最适合未来扩展(我不确定我将添加到此系统的新接口。)
  3. 这是我到目前为止所想的:

    为每个接口创建正确命名的方法

    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。如果我在这里发布了一个错误,请告诉我,我会在其他地方提出问题。

4 个答案:

答案 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));
    }
}