Difference between revisions of "The Blob"
CloudScale (Talk | contribs) (→Example) |
CloudScale (Talk | contribs) (→Problem) |
||
(9 intermediate revisions by one user not shown) | |||
Line 7: | Line 7: | ||
===Example=== |
===Example=== |
||
− | assume we have a process controller program. There are Controller and Valve Class as |
+ | Assume we have a process controller program. There are Controller and Valve Class as |
− | Figure 3.1 shows. This example is from [1]. |
+ | Figure 1 shows. This example is from [1]. |
+ | |||
[[File:Controller.png]] |
[[File:Controller.png]] |
||
+ | |||
+ | |||
+ | Figure 1: Excerpt from a class diagram for a process controller program [1] |
||
===Context=== |
===Context=== |
||
Line 17: | Line 20: | ||
===Problem=== |
===Problem=== |
||
− | this problem occurs when one class performs most of the system work relegating other |
+ | This problem occurs when one class performs most of the system work relegating other |
classes to minor, supporting roles. |
classes to minor, supporting roles. |
||
As in the example, the Controller does all the system work, openValve and closeValve. The Valve |
As in the example, the Controller does all the system work, openValve and closeValve. The Valve |
||
Line 25: | Line 28: | ||
For example, if the Controller wants to open the valve, it must get the current status from the valve |
For example, if the Controller wants to open the valve, it must get the current status from the valve |
||
first and tell the valve to open. See the code below: |
first and tell the valve to open. See the code below: |
||
− | ''void openValve() { |
+ | |
− | status currentStatus; |
+ | ''void openValve() {'' |
− | currentStatus = theValve->getStatus(); |
+ | ''status currentStatus;'' |
− | if (currentStatus != open) |
+ | ''currentStatus = theValve->getStatus();'' |
− | theValve->open(); |
+ | ''if (currentStatus != open)'' |
− | }'' |
+ | ''theValve->open();'' |
+ | ''}'' |
||
+ | |||
In the case when the valve is closed, it costs two messages to open the valve including one |
In the case when the valve is closed, it costs two messages to open the valve including one |
||
unnecessary message. This could potentially lead to unnecessary message traffic, which hinders |
unnecessary message. This could potentially lead to unnecessary message traffic, which hinders |
||
Line 36: | Line 39: | ||
===Solution=== |
===Solution=== |
||
− | keep related data and behaviour together. An object should have most of necessary data to |
+ | Keep related data and behaviour together. An object should have most of necessary data to |
make a decision. |
make a decision. |
||
As in the example of the Controller and the Valve, one possible solution to reduce the messages is to |
As in the example of the Controller and the Valve, one possible solution to reduce the messages is to |
||
check the valve status locally inside the Valve class (keep related data and behaviour together). |
check the valve status locally inside the Valve class (keep related data and behaviour together). |
||
So the openValve() operation in Controller is changed to: |
So the openValve() operation in Controller is changed to: |
||
− | void openValve() { |
+ | |
− | theValve->open(); |
+ | ''void openValve() {'' |
− | } |
+ | ''theValve->open();'' |
+ | ''}'' |
||
+ | |||
and the open() operation in Valve becomes: |
and the open() operation in Valve becomes: |
||
− | void open() { |
+ | |
− | if (status != open) |
+ | ''void open() {'' |
− | status = open; |
+ | ''if (status != open)'' |
− | } |
+ | ''status = open;'' |
+ | ''}'' |
||
+ | |||
Now it only requires one message to open the valve. |
Now it only requires one message to open the valve. |
||
Latest revision as of 15:24, 5 November 2013
Contents |
The Blob
Also Known As
The god class
Example
Assume we have a process controller program. There are Controller and Valve Class as Figure 1 shows. This example is from [1].
Figure 1: Excerpt from a class diagram for a process controller program [1]
Context
Systems with concurrency and mostly those that access a database.
Problem
This problem occurs when one class performs most of the system work relegating other classes to minor, supporting roles. As in the example, the Controller does all the system work, openValve and closeValve. The Valve simply reports its status (open or closed) and answers the Controller’s invocation, open and close respectively. The Controller requests information, make decisions and orders the Valve to open or close. For example, if the Controller wants to open the valve, it must get the current status from the valve first and tell the valve to open. See the code below:
void openValve() { status currentStatus; currentStatus = theValve->getStatus(); if (currentStatus != open) theValve->open(); }
In the case when the valve is closed, it costs two messages to open the valve including one unnecessary message. This could potentially lead to unnecessary message traffic, which hinders scalability.
Solution
Keep related data and behaviour together. An object should have most of necessary data to make a decision. As in the example of the Controller and the Valve, one possible solution to reduce the messages is to check the valve status locally inside the Valve class (keep related data and behaviour together). So the openValve() operation in Controller is changed to:
void openValve() { theValve->open(); }
and the open() operation in Valve becomes:
void open() { if (status != open) status = open; }
Now it only requires one message to open the valve.
Detection
Unkown
Variants
Unkown
Consequences
The anti-pattern potentially causes excessive message traffic.
See also
References
- C. Smith and L. Williams, Software Performance Antipatterns, in Proceedings of WOSP. ACM, 2000, pp. 127–136.