- Abstraction
- Encapsulation
- Polymorphism
- Inheritance
- Encapsulate what varies
- Favor composition over inheritance
- Program to an interface, not an implementation
- Strive for loosely coupled designs between objects that interact
- Classes should be open for extension, but closed for modification ( Open Closed )
- Depend upon abstractions. Do not depend upon concrete classes. ( Dependency Inversion )
- Talk only to your immediate friends. ( Principle of least knowledge )
- Don't call us, we call you. ( Hollywood Principle )
- A class should have only one reason to change. ( Single Responsibility Principle )
interface HashAlgorithm {
public Hash hash();
}
class SHA2 implements HashAlgorithm {
@Override
public Hash hash(){
return HashAlgorithms.get(this.class.getName()).hash();
}
}
Defines a one-to-many dependency between objects so that when one object changes state, all of its dependents are notified and updated automatically.
interface Subject {
public void registerObserver( Observer o );
public void removeObserver( Observer o );
public void notifyObservers();
}
interface Observer {
public void update();
}
Attaches additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
public class Decorator implements Component {
private Component wrappedObj;
public void operation();
}
Defines an interface for creating an object, but lets subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
abstract Product factoryMethod(String type);
Provides an Interface for creating families of related or dependent objects without specifying their concrete classes.
interface AbstractFactory {
public Product createProductA();
public Product createProductB();
}
public class Singleton {
private static Singleton uniqueInstance = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return uniqueInstance;
}
}
public enum Singleton {
UNIQUE_INSTANCE;
// more useful fields here
}
Encapsulates a request as an object, thereby letting you parameterize other objects with different requests, queue or log requests, and support undoable operations.
public interface Command {
public void execute();
public void undo();
}
Converts the interface of a class into another interface the clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.
class Adapter {
public void request();
}
Provides a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.
class HomeTheaterFacade {
public void watchMovie();
public void endMovie();
public void listenToRadio();
public void endRadio();
}
Defines the skeleton of an algorithm in a method, deferring some steps to subclasses. Template Method lets subclassesredefine certain steps of an algorithm without changing the algorithm's structure.
class TemplateClass {
templateMethod();
abstract primitiveOperation1();
abstract primitiveOperation2();
}
Provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
interface Iterator {
hasNext();
next();
remove();
}