"no client should be forced to depend on methods it does not use." Interface segregation is a Simple but useful pattern of SOLID principle, in other words, interface segregation is just about splitting an interface to several interfaces to make it simple working with classes those are going to implement the members.
Example
Suppose this interface :
public interface IAccountService { void CreateBankAccount(); void DeleteBankAccount(Guid accountId); void GetAllBankAccounts(); void GetAccountInfo(Guid accountId); }
and AccountService class
public class AccountService :IAccountService { public void CreateBankAccount() { throw new NotImplementedException(); } public void DeleteBankAccount(Guid accountId) { throw new NotImplementedException(); } public void GetAllBankAccounts() { throw new NotImplementedException(); } public void GetAccountInfo(Guid accountId) { throw new NotImplementedException(); } }
Account service class is one that admin uses it to access all the implemented method, now we need a UserService for users of the banking system to able to create the account, delete the account, get account information, to do this we implement the IAccountService to this service too, like this :
public class UserService : IAccountService { public void CreateBankAccount() { throw new NotImplementedException(); } public void DeleteBankAccount(Guid accountId) { throw new NotImplementedException(); } public Ilist<Account> GetAllBankAccounts() { throw new NotImplementedException(); } public Account GetAccountInfo(Guid accountId) { throw new NotImplementedException(); } }
All of the IAccountService members are necessary for UserService but GetAllBankAccounts(), because users of a bank couldn’t access to all account of the system! We can let the unnecessary members Not Implemented but It's so hideous, isn't it !? To solve this it's better to use Interface segregation pattern, simply add a new interface and change the IAccountService like this :
public interface IAccountService { IList<Account> GetAllBankAccounts(); } public interface IUserService { void CreateBankAccount(); void DeleteBankAccount(Guid accountId); Account GetAccountInfo(Guid accountId); }
And now implement both IAccountService and IUserService for AccountService
public class AccountService :IAccountService , IUserService { public IList<Account> GetAllBankAccounts() { throw new NotImplementedException(); } public void CreateBankAccount() { throw new NotImplementedException(); } public void DeleteBankAccount(Guid accountId) { throw new NotImplementedException(); } public Account GetAccountInfo(Guid accountId) { throw new NotImplementedException(); } }
And implement the IUserService members for UserService :
public class UserService : IUserService { public void CreateBankAccount() { throw new NotImplementedException(); } public void DeleteBankAccount(Guid accountId) { throw new NotImplementedException(); } public Account GetAccountInfo(Guid accountId) { throw new NotImplementedException(); } }
Now Every service class implements the needed members, right? If you take a closer look at this simple example rather than making the code more readable by using ISP, it is like the real world or business functionality, my mean every user is able to create, delete and get the account information and admin could see the list of all accounts rather than what Users could do .