From 2e98dcf2179f4aa13478d36fd8967d068a98eff0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 13 Sep 2020 17:39:10 +0300 Subject: [PATCH] Update README.md --- separated-interface/README.md | 43 +++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/separated-interface/README.md b/separated-interface/README.md index ca7a12e44..35c9e5fe0 100644 --- a/separated-interface/README.md +++ b/separated-interface/README.md @@ -10,23 +10,35 @@ tags: ## Intent -Separate the interface definition and implementation in different packages. This allows the client to be completely unaware of the implementation. + +Separate the interface definition and implementation in different packages. This allows the client +to be completely unaware of the implementation. ## Explanation Real world example -> An Invoice generator may be created with ability to use different Tax calculators that may be added in the invoice depending upon type of purchase, region etc. +> An Invoice generator may be created with ability to use different Tax calculators that may be +> added in the invoice depending upon type of purchase, region etc. In plain words -> Separated interface pattern encourages to keep the implementations of an interface decoupled from the client and its definition, so the client is not dependent on the implementation. +> Separated interface pattern encourages to keep the implementations of an interface decoupled from +> the client and its definition, so the client is not dependent on the implementation. -A client code may abstract some specific functionality to an interface, and define the definition of the interface as an SPI ([Service Programming Interface](https://en.wikipedia.org/wiki/Service_provider_interface) is an API intended and open to be implemented or extended by a third party). Another package may implement this interface definition with a concrete logic, which will be injected into the client code at runtime (with a third class, injecting the implementation in the client) or at compile time (using Plugin pattern with some configurable file). +A client code may abstract some specific functionality to an interface, and define the definition of +the interface as an SPI ([Service Programming Interface](https://en.wikipedia.org/wiki/Service_provider_interface) +is an API intended and open to be implemented or extended by a third party). Another package may +implement this interface definition with a concrete logic, which will be injected into the client +code at runtime (with a third class, injecting the implementation in the client) or at compile time +(using Plugin pattern with some configurable file). **Programmatic Example** -**Client** An Invoice generator class accepts the cost of the product and calculates the total amount payable inclusive of tax +**Client** + +`InvoiceGenerator` class accepts the cost of the product and calculates the total +amount payable inclusive of tax. ```java public class InvoiceGenerator { @@ -46,21 +58,23 @@ public class InvoiceGenerator { } ``` -The tax calculation logic is delegated to the ```TaxCalculator``` interface + +The tax calculation logic is delegated to the `TaxCalculator` interface. ```java - public interface TaxCalculator { double calculate(double amount); } - ``` **Implementation package** -In another package (which the client is completely unaware of) there exist multiple implementations of the ```TaxCalculator``` interface -```ForeignTaxCalculator``` which levies 60% tax for international products. + +In another package (which the client is completely unaware of) there exist multiple implementations +of the `TaxCalculator` interface. `ForeignTaxCalculator` is one of them which levies 60% tax +for international products. + ```java public class ForeignTaxCalculator implements TaxCalculator { @@ -74,7 +88,8 @@ public class ForeignTaxCalculator implements TaxCalculator { } ``` -```DomesticTaxCalculator``` which levies 20% tax for international products. +Another is `DomesticTaxCalculator` which levies 20% tax for international products. + ```java public class DomesticTaxCalculator implements TaxCalculator { @@ -88,7 +103,8 @@ public class DomesticTaxCalculator implements TaxCalculator { } ``` -These both implementations are instantiated and injected in the client class by the ```App.java``` class +These both implementations are instantiated and injected in the client class by the ```App.java``` +class. ```java var internationalProductInvoice = new InvoiceGenerator(PRODUCT_COST, new ForeignTaxCalculator()); @@ -101,9 +117,11 @@ These both implementations are instantiated and injected in the client class by ``` ## Class diagram + ![alt text](./etc/class_diagram.png "Separated Interface") ## Applicability + Use the Separated interface pattern when * You are developing a framework package, and your framework needs to call some application code through interfaces. @@ -117,3 +135,4 @@ Use the Separated interface pattern when ## Credits * [Martin Fowler](https://www.martinfowler.com/eaaCatalog/separatedInterface.html) +* [Patterns of Enterprise Application Architecture](https://www.amazon.com/gp/product/0321127420/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=0321127420&linkId=e08dfb7f2cf6153542ef1b5a00b10abc)