有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

公开多个接口的java技术(通过静态创建方法)

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

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

Weapon

public interface Weapon extends GameObject {
    Number attack();

    boolean addWeaponAttribute(WeaponAttribute attribute);
}

Firearm

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

我的问题是,让工厂生产具有不同接口的对象的最佳方式是什么?以下是我所想的“最好的结果”:

  1. 用户最清楚(很明显,他们要求什么,他们得到什么)
  2. 最适合未来的扩展(我不确定我将向这个系统添加哪些新接口)

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

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

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) {
        ...
    }
}

完全不同的东西

我愿意接受建议和改变。这是一个灵活的项目,因此我可以根据自己的意愿(就项目的这一部分而言)进行任何更改,以获得更好的结果

另外,作为旁注,我不确定这个问题是否过于开放。如果我在这里发错了帖子,请告诉我,我会把问题转移到别处


共 (4) 个答案

  1. # 1 楼答案

    使用泛型,您可能只需要一个工厂方法,如:

    public <T> T getObject(java.lang.Class<T> responseType, String name)
    

    然后用户会调用:

    Weapon weapon = factory.getObject(Weapon.class, "my weapon");
    
  2. # 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) {
            ...
        }
    }
    

    我认为不能向接口添加静态方法。如果你能的话,我也不推荐

  3. # 3 楼答案

    也许只是使用工厂方法设计模式,比如

    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));
        }
    }
    
  4. # 4 楼答案

    那一个工厂的工厂呢?每个工厂都将实施ifactory。Ifacorty需要一个方法实例化(字符串类型)并返回子类武器实例