Skip to main content

C# Example

/*
Interface Segregation Principle

- Interfaces should be segregated so that nobody who implements the interface will need to implement functions which they don't actually need.
*/

public class Document {
}

// not a good design as it forces different printer types to implement all of these features
public interface IMachine {
void Print(Document d);
void Scan(Document d);
void Fax(Document d);
}

// this is ok because this product uses all the features
public class MultiFunctionPrinter : IMachine {
public void Print(Document d) {}

public void Scan(Document d) {}

public void Fax(Document d) {}
}

// this is NOT ok because the product cannot scan and fax
public class OldFashionPrinter : IMachine {
public void Print(Document d) {}

// should not have this, even if throw an exception
public void Scan(Document d) {
throw new System.NotImplementedException();
}

// should not have this, even if throw an exception
public void Fax(Document d) {
throw new System.NotImplementedException();
}
}


// better to design interfaces separately in this case
public interface IPrinter {
void Print(Document d);
}

public interface IScanner {
void Scan(Document d);
}

// use multiple interface inheritance to implement multiple features
public class Photocopier : IPrinter, IScanner {
public void Print(Document d) {}

public void Scan(Document d) {}
}

// or can make an interface inherit multiple interfaces
public interface IMultiFunctionDevice : IScanner, IPrinter {}

public class MultiFunctionMachine : IMultiFunctionDevice {
/* method 1
public void Scan(Document d) {}

public void Print(Document d) {}
*/

// method 2
private IPrinter _printer;
private IScanner _scanner;

public MultiFunctionMachine(IPrinter printer, IScanner scanner) {
if (printer == null)
throw new System.ArgumentNullException(paramName: nameof(printer));
if (scanner == null)
throw new System.ArgumentNullException(paramName: nameof(scanner));
this._printer = printer;
this._scanner = scanner;
}

// Print will be delegated to _printer
public void Print(Document d) {
_printer.Print(d);
} // decorator pattern

// Scan will be delegated to _scanner
public void Scan(Document d) {
_scanner.Scan(d);
} // decorator pattern
}

public class Program {
public static void Main() {}
}