Java 构造函数注入
Java Constructor Injection
假设我有一个 class resources
实例化我所有的 OpenGL / Java 游戏对象,然后我通过构造函数将它们传递给我的场景 class (这需要它们),就像这样(简化示例)......
public class Resources {
Hero hero;
Enemy enemy;
MenuButtons mainMenuButtons;
Background background;
Scene mainMenu;
public void createObjects(){
hero = new Hero();
enemy = new Enemy();
mainMenuButtons = new MenuButtons();
background = new Background();
mainMenu = new Scene(hero, enemy, mainMenuButtons, background);
}
}
显然我场景的构造函数需要像这样接受 4 个参数:
public class MainMenu implements Scene {
hero Hero;
enemy Enemy;
mainMenuButtons MenuButtons;
background Background;
public MainMenu(Hero hero, Enemy enemy, MainMenuButtons mainMenuButtons, Background background){
this.hero = hero;
this.enemy = enemy;
this.mainMenuButtons = mainMenuButtons;
this.background = background;
}
}
随着需要更多的对象,构造函数变得越来越长。现在假设我改为执行以下操作:
public class MainMenu implements Scene {
Resources resources;
public MainMenu(Resources resources){
this.hero = resources.hero;
this.enemy = resources.enemy;
this.mainMenuButtons = resources.mainMenuButtons;
this.background = resources.background;
}
}
这两个选项都允许我在 mainMenuScene 中使用对象,如下所示:
hero.move();
第二个似乎更简洁一些,因为构造函数永远不需要接受任何额外的参数。 但是据我所知,我从未真正见过这样的例子。这是一种有效的技术吗?我 运行 使用它会遇到问题吗?
简短回答:-是的,该技术是有效的,应该可以正常工作。
较长的部分:-
我想建议两种设计方法来考虑
essence 模式
fluent界面模式
它们的意图相似。
构建器模式也很有用。我们多次看到它使用休眠。对于您的 class 它可能如下所示:-
public class mainMenu implements Scene {
private Hero hero;
private Enemy enemy;
private MenuButtons mainMenuButtons;
private Background background;
public mainMenu setHero(Hero hero){this.hero = hero; return this}
public mainMenu setEnemy(Enemy enemy){this.enemy = enemy; return this}
public mainMenu setMainMenuButtons(MenuButtons mainMenuButtons){this.mainMenuButtons = mainMenuButtons; return this}
public mainMenu setBackground(Background background){this.background = background; return this}
}
然后您可以使用如下链接创建对象:-
mainMenu main =new mainMenu().
setHero(new Hero()).
setEnemy(new Enemy()).
setMainMenuButtons(new MainMenuButtons()).
setBackground(new Background());
P.S。即使您不想使用上述模式,我也建议您进行三个改变或养成习惯。
1. Class 名称以大写字母开头并且
2. 按字母顺序组织参数的约定。
3. 可能您想将成员的访问级别设置为私有。
我喜欢。我喜欢将其称为 ApplicationContext
而不是 Resources
并使用相同的方式。
我因创建 "God Object" 而受到批评。我不同意这一点。只要 ApplicationContext 很薄并且只包含对象,但对它们一无所知(调用任何方法),就可以了。它可以用 List 或 Map 代替,但我喜欢额外的类型检查。
请参阅 Service Locator 模式以了解另一种执行此操作的方法。
假设我有一个 class resources
实例化我所有的 OpenGL / Java 游戏对象,然后我通过构造函数将它们传递给我的场景 class (这需要它们),就像这样(简化示例)......
public class Resources {
Hero hero;
Enemy enemy;
MenuButtons mainMenuButtons;
Background background;
Scene mainMenu;
public void createObjects(){
hero = new Hero();
enemy = new Enemy();
mainMenuButtons = new MenuButtons();
background = new Background();
mainMenu = new Scene(hero, enemy, mainMenuButtons, background);
}
}
显然我场景的构造函数需要像这样接受 4 个参数:
public class MainMenu implements Scene {
hero Hero;
enemy Enemy;
mainMenuButtons MenuButtons;
background Background;
public MainMenu(Hero hero, Enemy enemy, MainMenuButtons mainMenuButtons, Background background){
this.hero = hero;
this.enemy = enemy;
this.mainMenuButtons = mainMenuButtons;
this.background = background;
}
}
随着需要更多的对象,构造函数变得越来越长。现在假设我改为执行以下操作:
public class MainMenu implements Scene {
Resources resources;
public MainMenu(Resources resources){
this.hero = resources.hero;
this.enemy = resources.enemy;
this.mainMenuButtons = resources.mainMenuButtons;
this.background = resources.background;
}
}
这两个选项都允许我在 mainMenuScene 中使用对象,如下所示:
hero.move();
第二个似乎更简洁一些,因为构造函数永远不需要接受任何额外的参数。 但是据我所知,我从未真正见过这样的例子。这是一种有效的技术吗?我 运行 使用它会遇到问题吗?
简短回答:-是的,该技术是有效的,应该可以正常工作。
较长的部分:-
我想建议两种设计方法来考虑
essence 模式
fluent界面模式
它们的意图相似。
构建器模式也很有用。我们多次看到它使用休眠。对于您的 class 它可能如下所示:-
public class mainMenu implements Scene {
private Hero hero;
private Enemy enemy;
private MenuButtons mainMenuButtons;
private Background background;
public mainMenu setHero(Hero hero){this.hero = hero; return this}
public mainMenu setEnemy(Enemy enemy){this.enemy = enemy; return this}
public mainMenu setMainMenuButtons(MenuButtons mainMenuButtons){this.mainMenuButtons = mainMenuButtons; return this}
public mainMenu setBackground(Background background){this.background = background; return this}
}
然后您可以使用如下链接创建对象:-
mainMenu main =new mainMenu().
setHero(new Hero()).
setEnemy(new Enemy()).
setMainMenuButtons(new MainMenuButtons()).
setBackground(new Background());
P.S。即使您不想使用上述模式,我也建议您进行三个改变或养成习惯。
1. Class 名称以大写字母开头并且
2. 按字母顺序组织参数的约定。
3. 可能您想将成员的访问级别设置为私有。
我喜欢。我喜欢将其称为 ApplicationContext
而不是 Resources
并使用相同的方式。
我因创建 "God Object" 而受到批评。我不同意这一点。只要 ApplicationContext 很薄并且只包含对象,但对它们一无所知(调用任何方法),就可以了。它可以用 List 或 Map 代替,但我喜欢额外的类型检查。
请参阅 Service Locator 模式以了解另一种执行此操作的方法。