I read the Misko Hevery classic article on dependency injection and basically "separate the object creation code from the code logic."
The main idea is to "get rid of the" new "operators", put them in the selected objects ("Factories") and enter everything that you depend on. "
Now I can not imagine how to do this with objects consisting of several other components, and whose task is to isolate these components to the outside world.
Lame example
A Open class to represent a combination of several fields and a button. All components depend on the graphical context ui, but you want to hide it behind the interfaces of each subcomponent.
So, something like (in pseudo code, the language really doesn't matter, I think):
class CustomView() {
public CustomView(UIContext ui) {
this.ui = ui
}
public void start() {
this.field = new Field(this.ui);
this.button = new Button(this.ui, "ClickMe");
this.button.addEventListener(function () {
if (field.getText().isEmtpy()) {
alert("Field should not be empty");
} else {
this.fireValueEntered(this.field.getText());
}
});
}
public void addValueEnteredListener(Callback ...) {
}
public void fireValueEnteredListener(text) {
}
}
Callers will do something like:
ui =
v = new CustomView(ui);
v.addValueEnteredListener(function (text) {
});
Now this code has three βnewβ operators, and I'm not sure which of them Misko (and other DI proponents) stands for deliverance or how.
How to get rid of a new field () and a new button ()
Just enter it
I do not think the idea here is to actually introduce instances of the field and buttons, which could be done as follows:
class CustomView() {
public CustomView(Field field, Button button) {
this.field = field;
this.button = button;
}
public void start() {
this.button.addEventListener(function () {
if (field.getText().isEmtpy()) {
alert("Field should not be empty");
} else {
this.fireValueEntered(this.field.getText());
}
});
}
This makes the component code easier, and it actually hides the concept of a user interface, which is why the MetaForm component is clearly improved in terms of readability and verifiability.
, :
ui =
form = new Form(ui);
button = new Button(ui);
v = new CustomView(form, button);
v.addValueEnteredListener(function (text) {
});
, , , .
,
, -, , Factory .
class CustomView() {
public CustomView(Factory factory) {
this.factory = factory;
}
public void start() {
this.field = factory.createField();
this.button = factory.createButton();
this.button.addEventListener(function () {
if (field.getText().isEmtpy()) {
alert("Field should not be empty");
} else {
this.fireValueEntered(this.field.getText());
}
});
}
, Factory - ( Factory , , .)
factory =
v = new CustomView(factory);
v.addValueEnteredListener(function (text) {
});
, MetaForm , , "Mock" Factory, ... Mocks Field Button. , , ...
Yo 'Factory !!
Factory? , , - ( ), createXXXXX factory.
:
- Factory.createField
- Factory.createButton,
- Factory.createMetaForm , MetaForm (, MetaEditPage )
- , , factory.createMetaEditPage ..
- ... .
, :
- , "" , ( DI, Spring , )
- (UIWidgetFactory , ? Factory, ? ?)
C, Java , ApplicationProcessFactoryCreator.createFactory(). createProcess(). startApplication() ...
, :
: ,
, guice . :
class CustomView
@Inject
private Field fiedl;
@Inject
private Button button;
public void start() {
this.button.addEventListener(....
?
" " ? "singleton" ( ), " " ( , MetaForm?
, , , , (, ), .
DI , , . , , . , , ... , - ;)
, , , :
", , , ".
, , "fireClicked" , .
view.getButton(). fireClicked(), ...