使一个类更通用

时间:2015-03-28 16:54:41

标签: java oop design-patterns

这是我为游戏继承的一些代码。示例代码创建了Armor。

目前要制作一些新的装甲,你需要写一个新的课程。 E.g。

// Armor.java
public class Armor extends Item {   
    public int tier;

    public Armor( int tier ) {
        this.tier = tier;
    }
}

// ClothArmor.java    
public class ClothArmor extends Armor {
    {   
        name = "Cloth armor";
    }

    public ClothArmor() {
        super( 1 );
    }

    @Override
    public String desc() {
        return "Some Cloth Armor.";
    }
}

如何构建代码以使其更通用?从基于文本的配置文件中读取它似乎是显而易见的,但是当你想要创建具有特殊能力的Armor时,我可以看到这会遇到问题。

我是否可以使用任何资源或设计模式来确定如何继续?

2 个答案:

答案 0 :(得分:2)

如果您的目的是动态地向Armor添加某些行为,则可以使用装饰器设计模式。试着看看here。它是GoF书籍中最常用的模式之一,设计模式

因此,如果我确实理解您的需求,您可以从文件中读取要添加到基础Armor的属性,然后使用工厂将它们添加到装甲使用装饰模式。

interface Armor {
    // Put public interface of Armor here
    public String desc();
}
class BaseArmor extends Item implements Armor {
    public int tier;
    public BaseArmor( int tier ) {
        this.tier = tier;
    }
    public String desc() {
        return "A base armor ";
    }
}
// Every new possible feature of an armor has to extend this class
abstract class ArmorDecorator implements Armor {
    protected final Armor armor;
    // The armor that we want to decorate
    public ArmorDecorator(Armor armor) {
        this.armor = armor;
    }
}
// An armor that is made of cloth
class MadeOfCloth extends ArmorDecorator {
    public MadeOfCloth(Armor armor) {
        super(armor);
    }
    @Override
    public String desc() {
        // Decoration: we add a feature to the desc method
        return armor.desc() + "made of Cloth ";
    }
}
// The factory that reads the properties file and build armors
// using the information read.
enum ArmorFactory {
    INSTANCE;
    public Armor build() {
        Armor armor = null;
        // At this point you have to had already read the properties file
        if (/* An armor made of cloth */) {
            armor = new MadeOfCloth(new BaseArmor(1));
        }
        return armor;
    }
}

答案 1 :(得分:0)

总是很想为类型层次添加更多级别以添加功能。但这并不总是最佳途径。有时最好的途径是确定正交特征并改为提取它们。这里的关键是更喜欢组合而不是继承。

因此,在这种情况下,我会考虑ClothArmourArmour有何不同,ArmourItem的区别如何?我说ClothArmour与Armor的不同之处在于它与它有什么不同,以及它所适用的奖金。然后我说Armor通过它所装备的位置与Item区别开来。

然后我考虑完全摆脱ClothArmourArmour

Item clothArmour = new Item( 
                            EquipLocation.Chest, 
                            ComponentType.Cloth,
                            Bonuses.defenceOnEquip(1) );

为什么这是改进?它似乎更少面向对象。加载或保存这种格式相对简单。