- Abstraction (with information hiding allows to create a layer between a client and an internal implementation of a class, by exposing, extracting and implifying only the important data/behavior and hiding the irrelevant implementation details behind an abstract interface)
- Encapsulation (putting behavior/data into a class based on a responsibility it should have; use data hiding concept to hide the internal implementation details of the class behind an interface (public methods in the class). Make member variables (fields) and internally used methods private and expose only the minimal set of public methods. )
- Polymorphism (substitutability of objects with the same interface at run time)
- Inheritance (ability to inherit behavior/data (methods/fields) by the subclass (derived class) from the superclass (base class); use the inheritance only when you want to achieve code reuse only for the common behavior/data that doesn’t vary)
- Encapsulate what varies (put behavior that changes into separate classes implementing a behavior interface; use inheritance for the common behavior that stays the same for all subclasses to achieve code reuse)
- Favor composition over inheritance (enables flexibility – state/strategy design patterns where you can change implementation of the behavior at runtime)
- Program to interfaces not implementations (enables changes of the implementation without code change)
- create loosely coupled designs between objects that interact
- Classes should be opened for extension but closed for modification (public final method in the super class defining main system flow which is using abstract non-final protected template methods defining specific implementations in the subclasses)
- Depend on abstractions, do not depend on concrete classes
- Only talk to your friends (expose only the interface required, nothing more so that in case of internal implementation change you don’t need to change clients code, encapsulation, data hiding and abstraction)
- Don’t call us, we will call you (let the framework call your methods when needed and is configured to do so, enables you create loosely coupled systems, e.g. spring framework)
- A class should have only one reason to change (one class has only one responsibility, e.g. state class should only hold one state, more clear code)
- Hide the internal implementation details of the class behind an interface (public methods in the class). Make member variables (fields) and internally used methods private and expose only the minimal set of public methods.
- Your classes should not just have collections of fields and their accessors, not just storing data but provide behavior – so if you are making repeated calls for data using accessors, that’s a sign that some behavior should be moved to the object that has the data.
- Reference (identity) objects describes an object that is only one in the real world, e.g. Customer. All objects referencing the customer will reference the same object and changes to a customer are available to all the users of the Customer. You compare the references to the Customer by comparing their identities. Multiple Value objects can represent the same object (many object of the date 1-Jan-2009), Value objects are all interchangeable copies. You compare value objects by comparing the values they represent (not identities). Value objects should be immutable so that you don’t update the shared date unpredictably, just create an new date object. Value object may have identity but don’t use it for equality.
- Avoid storing unrelated or different types of objects into same collection. To store items use value objects or data objects (as opposed to storing every attribute in an ArrayList or HashMap). Provide wrapper classes around your
collections API classes like ArrayList, HashMap etc). E.g.: An order has an id and list of lineItems. Each lineItem has an id and productName. Good approach is to create an immutable final LineItem class via constructor (new LineItem(Long id, String productName)) and final id and final productName and expose only getters for these properties. Then add/remove each LineItem via interfaced add/remove(LineItem li) that internally will call add/remove on ArrayList<LineItem> and expose interfaced interator of this list.