Interface segregation principle
Joey Scarr (Talk | contribs) |
(→Example) |
||
(One intermediate revision by one user not shown) | |||
Line 4: | Line 4: | ||
A better way to solve this is to have small, distinct interfaces. In the case of our example we would have 3 interfaces for phone, camera and MP3 functionality. Now, modern cell phones can implement all three interfaces, while older cell phones may just implement the phone interface. This results in a cleaner design and implementation. | A better way to solve this is to have small, distinct interfaces. In the case of our example we would have 3 interfaces for phone, camera and MP3 functionality. Now, modern cell phones can implement all three interfaces, while older cell phones may just implement the phone interface. This results in a cleaner design and implementation. | ||
+ | |||
+ | == Example == | ||
+ | |||
+ | |||
+ | [[image:FatInterface.PNG]] | ||
+ | |||
+ | |||
+ | The example above shows a part of a typical ATM (Automated Teller Machine). A transaction that the | ||
+ | ATM performs can be classified as a transaction of deposits, withdrawals and transfers, as shown on the | ||
+ | diagram above. These subclasses all uses the UI interface. This interface is a typical example of a “fat” | ||
+ | interface: it contains everything that its users need, yet every user needs only part of it. This is a | ||
+ | violation of the “Interface-Segregation Principle” (ISP), which states that clients should not be forced | ||
+ | to depend upon interfaces that they do not use. If we would need to change a subclass of | ||
+ | Transaction, that would mean that UI would also need to change, together with all other classes | ||
+ | that depend on UI (like the other subclasses of Transaction). The solution to this problem is to | ||
+ | break (or segregate) the interface into smaller, more specialized interfaces. Again, the “Extract | ||
+ | Interface” recapturing should do the trick. In this case, there are three types of transactions, so we'll | ||
+ | segregate the UI interface into three smaller ones: DepositUI for deposits (with | ||
+ | ''requestDepositAmount()'' method), ''WithdrawalUI'' for withdrawals (with | ||
+ | ''requestWithdrawalAmount()'' and ''informInsufficientFunds()'' methods) and | ||
+ | ''TransferUI'' for transfers (with ''requestTransferAmount()'' method). | ||
+ | |||
+ | |||
+ | The UML diagram bellow shows the possible fix to this problem: | ||
+ | |||
+ | |||
+ | [[image:FatInterfaceFix.PNG]] | ||
== See Also == | == See Also == |
Latest revision as of 10:27, 18 October 2010
Interface Segregation Principle, by Robert Martin says that clients should not be forced to depend upon interfaces that they do not use. Put more simply, many client specific interfaces are better than one general purpose interface. This principle prevents Fat interfaces surfacing in the design.
A good example of this principle is a modern cellphone which, in addition to a phone, is also a camera and an MP3 player. However some cellphones, especially older ones, do not have camera or MP3 player. Now imagine that we have an interface which provides access to the phone, camera and MP3 functionality. This would be quite a fat interface. If an older cellphone wishes to use this interface, the camera and MP3 functionality will appear to be present, but won't actually work.
A better way to solve this is to have small, distinct interfaces. In the case of our example we would have 3 interfaces for phone, camera and MP3 functionality. Now, modern cell phones can implement all three interfaces, while older cell phones may just implement the phone interface. This results in a cleaner design and implementation.
Example
The example above shows a part of a typical ATM (Automated Teller Machine). A transaction that the
ATM performs can be classified as a transaction of deposits, withdrawals and transfers, as shown on the
diagram above. These subclasses all uses the UI interface. This interface is a typical example of a “fat”
interface: it contains everything that its users need, yet every user needs only part of it. This is a
violation of the “Interface-Segregation Principle” (ISP), which states that clients should not be forced
to depend upon interfaces that they do not use. If we would need to change a subclass of
Transaction, that would mean that UI would also need to change, together with all other classes
that depend on UI (like the other subclasses of Transaction). The solution to this problem is to
break (or segregate) the interface into smaller, more specialized interfaces. Again, the “Extract
Interface” recapturing should do the trick. In this case, there are three types of transactions, so we'll
segregate the UI interface into three smaller ones: DepositUI for deposits (with
requestDepositAmount() method), WithdrawalUI for withdrawals (with
requestWithdrawalAmount() and informInsufficientFunds() methods) and
TransferUI for transfers (with requestTransferAmount() method).
The UML diagram bellow shows the possible fix to this problem: