Getting rid of β€œnew” operators for subcomponent objects

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());
           }
      });
   }

   // The interface of this component is that callers
   // subscribe to "addValueEnteredListener"..)
   public void addValueEnteredListener(Callback ...) {
   }

   public void fireValueEnteredListener(text) {
     // Would call each listeners in turn
   }
}

Callers will do something like:



// Assuming a UIContext comes from somewhere...
ui = // Wherever you get UI Context from ?
v = new CustomView(ui);
v.addValueEnteredListener(function (text) {
 // whatever...
});

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());
           }
      });
   }

   // ... etc ... 

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.

, :



// Assuming a UIContext comes from somewhere...

ui = // wherever ui gets injected from 

form = new Form(ui);
button = new Button(ui);

v = new CustomView(form, button);
v.addValueEnteredListener(function (text) {
 // whatever...
});

, , , .

,

, -, , 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());
           }
      });
   }

   // ... etc ... 

, Factory - ( Factory , , .)



// Assuming a UIContext comes from somewhere...

factory = // wherever factory gets injected from 

v = new CustomView(factory);
v.addValueEnteredListener(function (text) {
 // whatever...
});

, 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(....

// etc...

?

" " ? "singleton" ( ), " " ( , MetaForm?

, , , , (, ), .

DI , , . , , . , , ... , - ;)

, , , :

", , , ".

, , "fireClicked" , .

view.getButton(). fireClicked(), ...

+5
2

, DI Framework (Spring Guice) factory. field/constructor/set, DI Framework . .

0

, " "?

, DI - , , . , , ( CustomView) . , , , .

0

All Articles