As a part of an overall strategy of agile and adaptive programming, a number of object-oriented design principles were proposed for the design and programming of computer software system that is easy to maintain and extend over time. These principles are guidelines intended for programmers to apply while working on software to remove "code smells" (potentially buggy code) by refactorizing the source code until it is both legible and extensible. In this page, we introduce the SOLID principles, that is, Single responsibility, Open-closed, Liskov substitution, Interface segregation and Dependency inversion. The following information was integrated from various sources on the Web.
Example: If a class
keeps information about a sales order, and in addition has a
saveOrder() that saves the
in a database and a method
SalesOrder in XML format, this design
will violate the SRP because there will be different types of
users of this class and different reasons for making changes to
this class. A change made for one type of user, say change the
type of database, may require the re-test, recompilation, and
re-linking of the class for the other type of users.
A better design will be to have the
class only keeps the information about a sales order, and have
different classes to save order and to export order, respectively.
Such a design will confirm to SRP.
The OCP requires that each software entity should be open for extension, but closed for modification.
Example: Suppose an
class has a method
validate(Order order) that is
programmed to validate an order based on a set of hard-coded
rules. This design violates the OCP because if the rules
OrderValidation class has to be
modified, tested, and compiled.
A better design will be to let the
class contain a collection of
objects each of which has a
order) method (perhaps defined in a
interface) to validate an
Order using a specific
rule, and the
validate(Order order) method of
simply iterate through those
to validate the order. The new design will satisfy the OCP,
because if the rules change, we can just create a new
object and add it to an
OrderValidation instance at
run time (rather than to the class definition itself).
This is can also be achieved by using subclasses of a base
AbstractValidationRule that has an
Subclasses can implement the method differently without changing
the base class functionality.
The LSP requires that objects in a program should be replaceable with instances of their subclasses without altering the correctness of that program.
The users must be able to use objects of subclasses via references to base classes without noticing any difference. When using an object through its base class interface, the object of a subclass must not expect the user to obey preconditions that are stronger than those required by the base class.
Example: Suppose a
class has two instance variables
and a method
setSize(int a, int b), which set
Square is a subclass of
and it overrides the inherited method by setting both
a. This design will
violate LSP. To see this, consider a client uses a reference
variable of type
Rectangle to call the
method to assign different values of
and then immediately verify if the sizes were set correctly or the
area is correctly computed. The results will be different if the
variable references to a
Rectangle object than to a
It turns out that in OO programming, a
is not a
ectangle at all because it
behaves differently from a
The ISP requires that clients should not be forced to depend on interfaces that they do not use.
Example: Suppose a Vehicle interface shown in the figure is designed for clients to use
HighWaydoes not use
ParkingLotdoes not need
The DIP requires that high level modules should not depend on low level modules, both should depend on abstraction. Also, abstraction should not depend on details, details should depend on abstractions.
Example: Making a class
associate to another class
Lamp (because a
Button) is a violation of DIP. A better design
will be associate an AbstractButton with an AbstractButtonClient,
and define Button as a subclass of the AbstractButton and a Lamp a
subclass of the AbstractButtonClient.
Example: Making an
class to use
PDFBook class is a violation of DIP
because it requires to change the
to read other types of e-books. A better design is to let
use an interface
EBook and let
and other types of e-book classes implement
Now adding or changing e-book classes will not require any change