另一个针对特定问题的设计问题

发布于 2024-11-25 10:08:42 字数 621 浏览 1 评论 0原文

假设我有一个具有某些可配置技能的忍者。通过可配置,我的意思是程序读取配置文件并在运行时添加它们。即:

Ninja:
  color: Red
  Skills:
    - High Jump
    - Invisibility

现在,假设这些技能需要动态地向 Ninja 类添加功能。例如,如果我们将 Ninja 配置为具有跳高技能,则该类需要遵循 CanHighJump 接口,并使用 public void highJump() 作为方法。

现在我可以想到两种方法来解决这个问题。我的第一反应是创建一个带有字符串颜色的 Ninja 类,然后使用 Reflection 添加功能。然而,现在我意识到我也可以通过关系数据库来做到这一点。有一个带有字符串颜色的 Ninja 类,并且忘记任何将 Ninjas 与技能相关的对象 - 相反,每当我需要检查技能时,只需调用数据库来检索该类可以使用的可能技能。这是我能想到的仅有的两个真正动态的解决方案,我无法理解每个方案的设计优缺点。我有一种感觉,数据库解决方案的可扩展性会更高,但在编码时,反射方法对我来说最有意义。无需查询Ninja有哪些技能,因为我可以轻松查看界面。

我希望有人能给我一些关于这个问题的标准设计解决方案的见解。无论是我想到的两个之一,还是更可能是我没有想到的。

Say I have a Ninja with certain configurable skills. By configurable, I mean the program reads in a configuration file and adds them in at runtime. ie:

Ninja:
  color: Red
  Skills:
    - High Jump
    - Invisibility

Now, assume these skills need to dynamically add functionality to the Ninja class. As in, if we configure Ninja to have a High Jump skill, then the class needs to follow the CanHighJump Interface, with public void highJump() as a method.

Now there are two ways I can think of going about this. My first reaction would be to have a Ninja class with String color and then use Reflection to add in the functionality. However, now I realize I could do it through a relational database as well. Have a Ninja class with String color, and forget about any objects relating Ninjas with Skills - instead, whenever I need to check for a skill, just make a call to the database retrieving the possible skills that class can use. Those are the only two truly dynamic solutions I can come up with, and I can't comprehend the design pros/cons of each. I have a feeling the database solution would be far more scale-able, but the reflection method would make most sense to me when coding. No need to query which skills a Ninja has, because I could easily check for the interface.

I'm hoping someone can give me a bit of insight over a standard design solution for this problem. Whether it be one of the two I came up with, or more likely something i didn't think of.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

魂牵梦绕锁你心扉 2024-12-02 10:08:42

看来您正在寻找的内容接近 功能模式

public interface IHasSkills {
    public <T> getSkill(Class<T> skill);
}

public interface ICanAddSkills extends IHasSkills {
    public void addSkill(ISkill skill)
}

public class Ninja implements ICanAddSkills {
    private List<ISkill> _skills;

    public void addSkill(ISkill skill) {
        _skills.Add(skill);
    }

    public <T> GetSkill(Class<T> skillType) {
        for(ISkill skill : _skills) {
           if(skill instanceof skillType) return skill;
        }
        return null;
    }
}

public interface ISkill{}

public interface IHighjumpSkill extends IHighJumpCapable{
    public void highJump();
}

public class NinjaHighJumpSkill implements IHighJumpCapable{
    private Ninja _canHighJump;
    public NinjaHighJumpSkill(Ninja ninja) {
        _canHighJump = ninja;
    }

    @Override
    public void highJump() {
        //Note that this could be combined with the [Property Pattern][2] 
        //(which was referenced in another answer) to set/get arbitrary
        //properties on the ninja.
        _canHighJump.DoWhateverAHighJumpDoes();
    }
}

您可以使用此模式向对象添加新功能,而无需在对象中实际实现它们。如果忍者具有此技能,则客户端在调用 myNinja.getSkill(IHighJumpCapable.class) 时将获得一个 IHighJumpCapable 实例,否则返回 null。然后,您可以调用 IHighJumpCapable 上的 highJump() 方法。

public static void Main(String args[]) {
    Ninja ninja = new Ninja();
    ninja.AddSkill(new NinjaHighJumpSkill(ninja));
    IHighJumpCapable canHighJump = ninja.GetSkill(IHighJumpCapable.class);
    canHighJump.highJump();
}

It seems like what you're looking for is close to the Capability Pattern.

public interface IHasSkills {
    public <T> getSkill(Class<T> skill);
}

public interface ICanAddSkills extends IHasSkills {
    public void addSkill(ISkill skill)
}

public class Ninja implements ICanAddSkills {
    private List<ISkill> _skills;

    public void addSkill(ISkill skill) {
        _skills.Add(skill);
    }

    public <T> GetSkill(Class<T> skillType) {
        for(ISkill skill : _skills) {
           if(skill instanceof skillType) return skill;
        }
        return null;
    }
}

public interface ISkill{}

public interface IHighjumpSkill extends IHighJumpCapable{
    public void highJump();
}

public class NinjaHighJumpSkill implements IHighJumpCapable{
    private Ninja _canHighJump;
    public NinjaHighJumpSkill(Ninja ninja) {
        _canHighJump = ninja;
    }

    @Override
    public void highJump() {
        //Note that this could be combined with the [Property Pattern][2] 
        //(which was referenced in another answer) to set/get arbitrary
        //properties on the ninja.
        _canHighJump.DoWhateverAHighJumpDoes();
    }
}

You can use this pattern to add new capabilities to an object without having to actually implement them in the object. The client will get an instance of IHighJumpCapable when they call myNinja.getSkill(IHighJumpCapable.class) if the ninja has this skill, or null otherwise. You can then call the highJump() method on the IHighJumpCapable.

public static void Main(String args[]) {
    Ninja ninja = new Ninja();
    ninja.AddSkill(new NinjaHighJumpSkill(ninja));
    IHighJumpCapable canHighJump = ninja.GetSkill(IHighJumpCapable.class);
    canHighJump.highJump();
}
喜爱纠缠 2024-12-02 10:08:42

这是瑞安建议的一种延伸。如果需要,以下方法将使忍者执行技能,而无需询问和检查技能类型。

看看这是否会增加价值 -

public class Ninja implements ICanAddSkills {
private List<ISkill> _skills;

public void addSkill(ISkill skill) {
    _skills.Add(skill);
}

public <T> getSkill(Class<T> skillType) {
    for(ISkill skill : _skills) {
       if(skill instanceof skillType) return skill;
    }
    return null;
    }
}

    public interface ISkill{
        public void performSkill();
    }

public interface IHighjumpSkill extends ISkill,IHighJumpCapable{
    public void highJump();
}

public class NinjaHighJumpSkill implements IHighjumpSkill{
    private Ninja _canHighJump;
    public NinjaHighJumpSkill(Ninja ninja) {
        _canHighJump = ninja;
    }

    @Override
    public void highJump() {
        _canHighJump.DoWhateverAHighJumpDoes();
    }

    // delgate to whatever this skill can do
    @Override
    public void performSkill() {
        highJump();
    }
}


public static void Main(String args[]) {
    Ninja ninja = new Ninja();
    ninja.AddSkill(new NinjaHighJumpSkill(ninja));
    // loop through skills and perform actions using performSkill()

     for(ISkill skill : _skills) {
          skill.performSkill();
        }

}

This is a sort of extension to what Ryan has suggested. The following way will make a ninja perform the skill without necessarily asking and checking the skill type if this is desired.

See if this adds value -

public class Ninja implements ICanAddSkills {
private List<ISkill> _skills;

public void addSkill(ISkill skill) {
    _skills.Add(skill);
}

public <T> getSkill(Class<T> skillType) {
    for(ISkill skill : _skills) {
       if(skill instanceof skillType) return skill;
    }
    return null;
    }
}

    public interface ISkill{
        public void performSkill();
    }

public interface IHighjumpSkill extends ISkill,IHighJumpCapable{
    public void highJump();
}

public class NinjaHighJumpSkill implements IHighjumpSkill{
    private Ninja _canHighJump;
    public NinjaHighJumpSkill(Ninja ninja) {
        _canHighJump = ninja;
    }

    @Override
    public void highJump() {
        _canHighJump.DoWhateverAHighJumpDoes();
    }

    // delgate to whatever this skill can do
    @Override
    public void performSkill() {
        highJump();
    }
}


public static void Main(String args[]) {
    Ninja ninja = new Ninja();
    ninja.AddSkill(new NinjaHighJumpSkill(ninja));
    // loop through skills and perform actions using performSkill()

     for(ISkill skill : _skills) {
          skill.performSkill();
        }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文