The General Responsibility Assignment Software Pattern (GRASP) guides in assigning responsibilities to collaborating objects. The GRASP principles aim to make software design more maintainable, modular, and reusable by providing a better understanding of how to distribute responsibilities among different parts of the software system.
Responsibility Driven Design (RDD)
RDD is an approach that focuses on defining the responsibilities of classes and objects within a system. Responsibility is a contract or obligation of a class
Responsibilities are assigned to classes of objects during object design, RDD encourages a top-down approach, where designer starts by designing high-level responsibilities and then decompose them into smaller responsibilities, eventually assign them to specific classes.
A class must know its responsibility
-
Private encapsulated data Some data should be encapsulated and hidden from other classes, promoting data integrity and preventing unintended modifications.
-
Related objects A class should be aware of the other classes it collaborates with. This awareness allows objects to interact and fulfil their responsibilities.
-
Things it can derive or calculate A class should know what data it can derive or calculate based on its responsibilities.
A class must do its responsibility
-
Take action (create objects, do calculations) A class should be able to perform actions related to its responsibilities.
-
Initiate action in other objects Sometimes, a class might need to trigger actions in other classes to fulfil its responsibilities.
-
Control/coordinate actions in other objects Controller classes help manage the flow of information and actions between different parts of the system.
Responsibility Examples
”A Sale
is responsible for knowing its total” (knowing)
Knowing responsibilities are related to attributes, associations in the domain model
”A Sale
is responsible for creating SalesLineItems
” (doing)
Doing responsibilities are implemented by means of methods.
Methodological approach to OO design
The five basic principles
- Creator
- Information Expert
- High Cohesion
- Low Coupling
- Controller
Creator principle
Assign class B the responsibility to create an instance of a class A if one of these is true:
B “contains” A
A has a “part of” relationship between B, which can be aggregation or composition. This containment implies a strong relationship where B manages the life cycle of A.
B “records” A
If B is responsible for recording instances of class A (storing or keeping track of them), then class B should create instances of class A.
e.g. A Library
class that keeps track of Book
records might be responsible for creating new Book
instances when new book record is to be added.
B “closely uses” A
When class B uses class A’s instances frequently, it is practical for B to create instances of A. This is often when functionality of A is essential to the operation of B.
B “has the initial data for” A
If class B has the data necessary to initialise objects of class A, then it is suitable for B to create instances of A.
Information expert principle
Assign responsibility to the classes that has the information needed to fulfil it. All methods that work with data (variables, files) should be in the same place where data exist.
In this shopping cart example, the Cart
class should be responsible for calculating the total price since it holds all the Item
objects.
Low coupling principle
Design classes with minimal dependencies on other classes. Low coupling reduces the impact of changes, making system more maintainable and scalable.
For more details with example, proceed to Low Coupling Principle.
High cohesion
Design classes that their responsibilities are strongly related and highly focused. High cohesion makes classes easier to maintain and understand.
In this example, a UserManager
class should only handle user-related responsibilities such as user authentication, and not handle tasks like logging or database connections.
Controller
A controller assigns responsibilities of handling system events to a class. The controller can either:
- Represent the entire system (Structural Patterns - Facade Pattern)
- Represent a use case scenario.
The controller class represents the login use case of a software system. It acts as an intermediary in the context of a MVC system.
Back to parent page: Web and Application Development
Design_PrincipleSOFT2201GRASP_design_principlesResponsibility_driven_designRDD