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

pse*_*ble 5 java design-patterns factory-pattern

我目前正在做一个项目,在该项目中我试图隐藏尽可能多的关于我创建的层次结构的细节。我想这样做是为了最大限度地减少用户需要了解的有关对象的信息量(并控制他们可以对对象状态执行的操作)。此外,我使用该模式来限制应用程序可以创建的对象类型,并将其限制为从工厂创建。

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

Weapon

public interface Weapon extends GameObject {
    Number attack();

    boolean addWeaponAttribute(WeaponAttribute attribute);
}
Run Code Online (Sandbox Code Playgroud)

Firearm

public interface Firearm extends Weapon {
    void reload(Number rounds);
}
Run Code Online (Sandbox Code Playgroud)

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

  1. 用户最清楚(很明显他们要求什么以及他们得到什么)
  2. 未来扩展的最佳选择(我不确定我将向该系统添加哪些新接口)。

到目前为止,这是我一直在想的:

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

public static Firearm getFirearm(String firearmName) {
    ...
}

public static Weapon getWeapon(String weaponName) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

执行上述操作,但在单独命名的类中生成工厂

public class WeaponFactory {
    public static Weapon getWeapon(String weaponName) {
        ...
    }
}


public class FirearmFactory {    
    public static Firearm getFirearm(String firearmName) {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

完全不同的东西

我愿意接受建议和改变。这是一个灵活的项目,因此我可以随心所欲地进行更改(就项目的这一部分而言)以取得更好的结果。

另外 - 作为旁注,我不确定这个问题对 SO 来说是否过于开放。如果我在这里发帖有误,请告诉我,我会将我的问题移到别处。

Ray*_*yek 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));
    }
}
Run Code Online (Sandbox Code Playgroud)