Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I hope I understand your question correctly.</p> <p><strong>Injecting Dependencies</strong></p> <p>No we don't pass the dependencies through all the layers. We only pass them to layers that directly talk to them. For example:</p> <pre><code>public class PaymentHandler { private customerRepository; public PaymentHandler(CustomerRepository customerRepository) { this.customerRepository = customerRepository; } public void handlePayment(CustomerId customerId, Money amount) { Customer customer = customerRepository.findById(customerId); customer.charge(amount); } } public interface CustomerRepository { public Customer findById(CustomerId customerId); } public class DefaultCustomerRepository implements CustomerRepository { private Database database; public CustomerRepository(Database database) { this.database = database; } public Customer findById(CustomerId customerId) { Result result = database.executeQuery(...); // do some logic here return customer; } } public interface Database { public Result executeQuery(Query query); } </code></pre> <p><code>PaymentHandler</code> does not know about the <code>Database</code>, it only talks to <code>CustomerRepository</code>. The injection of <code>Database</code> stops at the repository layer.</p> <p><strong>Readability of the code</strong></p> <p>When doing manual injection without framework or libraries to help, we might end up with Factory classes that contain many boilerplate code like <code>return new D(new C(new B(), new A());</code> which at some point can be less readable. To solve this problem we tend to use DI frameworks like <strong>Guice</strong> to avoid writing so many factories. </p> <p>However, for classes that actually do work / business logic, they should be more readable and understandable as they only talk to their direct collaborators and do the work they need to do.</p> <p><strong>Unit Testing</strong></p> <p>I assume that by "Top" layer you mean the <code>PaymentHandler</code> class. In this example, we can create a stub <code>CustomerRepository</code> class and have it return a <code>Customer</code> object that we can check against, then pass the stub to the <code>PaymentHandler</code> to check whether the correct amount is charged.</p> <p>The general idea is to pass in fake collaborators to control their output so that we can safely assert the behavior of the class under test (in this example the <code>PaymentHandler</code> class). </p> <p><strong>Why interfaces</strong></p> <p>As mentioned in the comments above, it is more preferable to depend on interfaces instead of concrete classes, they provide better testability(easy to mock/stub) and easier debugging.</p> <p>Hope this helps.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload