请原谅我糟糕的术语!
我一直在努力解决问题。
我在java中制作游戏引擎,我经常遇到同样的问题。我有这个类层次结构:
父母 - >儿童 - >孙子
PARENT拥有并构建CHILD等等。
现在,父母有能力执行CHILD和GRANDCHILD在执行期间需要做的事情。让我们说GRANDCHILD是GUI中的按钮,PARENT是游戏的核心。如果按下按钮我想暂停游戏。按钮/ GRANDCHILD本身无法做到这一点,但需要通过PARENT / CORE来完成。
父母 - >儿童 - >孙子 +暂停游戏()+做某事()
我有三个解决这个问题的方法,没有一个能让我满意。
PARENT int:click() - > CHILD int:click() - > GRANCHILD int:点击()
父母的功能
switch(CHILD.click(){
case 1 do this;
case 2: do that;
etc.
}
这是我最讨厌的解决方案。我不仅需要跟踪整数/枚举,而且当我可以使用多态来获得更清晰的代码时,我还需要使用switch / if-else。
我认为这种方法称为回叫。在构造时,PARENT发送一个内部类/一组函数,它们被传递给GRANDCHILD的构造函数。 GRANDCHILD保存此内部类实例并在需要时调用其方法。
class PARENT {
孩子;
PARENT(){ child = new CHILD(新控制器); }
类控制器{
public void click(){ 做东西... }
}
}
这没关系,但感觉不对。游戏核心可能有数百个儿童,这意味着数百个内部类,其功能可能或多或少相同。随着游戏的发展,课程将变得非常庞大。这也会在层次结构中产生循环,我感觉很糟糕。
如果只有少数几个课程需要访问,我可以忍受这个。问题是我几乎每个人都需要相互沟通!
那我该怎么办?我是否遗漏了一些东西,如果没有,上述哪种方法是最佳做法,可以免除未来的麻烦?
答案 0 :(得分:1)
这主要取决于您的编码风格。 如果您经常查看一些游戏库,可以使用单例或其他模式从代码中的任何位置调用主要核心对象(您的核心,输入等)。
如果使用Java 1.8,则可以使用回调功能,而无需编写大量内部类。
//in your child/grandchild
public void doStuff(Runnable callback){
//do stuff
callback.run();
}
您可以将method references传递给这些方法
//somewhere else
child.doStuff(core::myCallbackFunction);
您可以使用功能接口以这种方式传递许多不同的消费者/供应商/功能,因此您也可以使用参数和返回值编写回调。
但是,大多数情况下,它取决于您认为最适合您的编码风格。
答案 1 :(得分:0)
关于你的帖子有点令人困惑的一点是,这里的'父母'和'孩子'实际上不是面向对象意义上的父母和孩子,而只是交互对象。因此,任何特定功能都只能由相关类处理 - 不需要让其他对象来回传递消息。
对于GUI元素(如按钮),请考虑使用侦听器。使核心实现一个合适的Listener接口并将其添加到每个元素 - 这是Observer设计模式,有点类似于回调方法。