Jump to content

Balking pattern: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
Amiceli (talk | contribs)
No edit summary
tag as stub
(39 intermediate revisions by 27 users not shown)
Line 1: Line 1:
{{Multiple issues|
The '''Balking pattern''' is a [[design pattern (computer science)|software design pattern]] that only executes an action on an [[object (computer science)|object]] when the object is in a particular state. For example, if an object reads [[ZIP file format|ZIP]] files and a calling method invokes a get method on the object when the ZIP file is not open, the object would "balk" at the request. In the [[Java (programming language)|Java]] programming language, for example, an IllegalStateException might be thrown under these circumstances.
{{More citations needed|date=December 2010}}
{{More footnotes|date=December 2010}}
{{lead extra info |date=July 2023}}
}}


The '''balking pattern''' is a [[design pattern (computer science)|software design pattern]] that only executes an action on an [[object (computer science)|object]] when the object is in a particular state. For example, if an object reads [[ZIP file format|ZIP]] files and a calling method invokes a get method on the object when the ZIP file is not open, the object would "balk" at the request. In the [[Java (programming language)|Java]] programming language, for example, an <code>IllegalStateException</code> might be thrown under these circumstances.
There are some in this field that think this is more of an Anti-Pattern, than a design pattern. If an object cannot support its API, it should either limit the API so that the offending call is not available or it should
* be created in a sane state
* not make itself available until it is in a sane state
* become a façade and answer back an object that is in a sane state
… so that the call can be made without limitation.


There are some specialists{{who|date=November 2010}} in this field who consider balking more of an [[anti-pattern]] than a design pattern. If an object cannot support its [[API]], it should either limit the API so that the offending call is not available, or so that the call can be made without limitation. It should:
==Code Example==
* Be created in a "sane state";{{elucidate|date=April 2015}}
* not make itself available until it is in a sane state;
* become a [[Facade pattern|facade]] and answer back an object that is in a sane state.


==Usage==
Suppose that a class were created for an electronic flusher. The main method, flush, would be called when the user wants the toilet to be flushed. If there is more than one call to the method during a flush, the method would balk at the request, and return nothing. See the source code below for an example.
Objects that use this pattern are generally only in a state that is prone to balking temporarily but for an unknown amount of time.{{Citation needed|date=May 2009}} If objects are to remain in a state which is prone to balking for a known, finite period of time, then the [[guarded suspension pattern]] may be preferred.


==Implementation==
<source lang="java">
Below is a general, simple example for an implementation of the balking pattern.<ref name=Grand>{{cite book| last = Grand | first = Mark| title = Patterns in Java, Volume 1: A Catalog of Reusable Design Patterns Illustrated with UML, Second Edition| year = 2002| publisher = John Wiley & Sons| location = Indianapolis, Ind}}</ref> As demonstrated by the definition above, notice how the "synchronized" line is utilized. If there are multiple calls to the job method, only one will proceed while the other calls will return with nothing. Another thing to note is the <code>jobCompleted()</code> method. The reason it is synchronized is because the only way to guarantee another thread will see a change to a field is to synchronize all access to it. Actually, since it is a boolean variable, it could be left not explicitly synchronized, only declared volatile - to guarantee that the other thread will not read an obsolete cached value.
public class Flusher {
private boolean flushInProgress = false;


<syntaxhighlight lang="java">
/**
public class Example {
* This method is called to start a flush.
private boolean jobInProgress = false;
*/
public void flush() {
synchronized (this) {
if (flushInProgress)
return;
flushInProgress = true;
}
// code to start flush goes here.
...
}


public void job() {
/**
synchronized(this) {
* This method is called to notify this object that a
if (jobInProgress) {
* flush has completed.
*/
return;
void flushCompleted() {
}
flushInProgress = false;
jobInProgress = true;
} // flushCompleted()
}
// Code to execute job goes here
} // class Flusher
// ...
</source>
jobCompleted();
}


void jobCompleted() {
If the <code>flush</code> method is called while a flush is in progress, the method balks.
synchronized(this) {
jobInProgress = false;
}
}
}
</syntaxhighlight>


==See also==
Notice the use of the <code>synchronized</code> statement in the <code>flush</code> method. It is there to ensure that if multiple calls to the <code>flush</code> method occur at the same time, the result is predictable. Exactly one of the calls will proceed normally and the others will balk. Without the synchronized statement, multiple calls could proceed normally at the same time.
*[[Read and write lock pattern]]

*[[Guarded suspension|Guarded suspension pattern]]
Also, notice that the <code>flushCompleted</code> method is not synchronized. This is because there is never a time when setting the <code>flushInProgress</code> variable to false causes a problem. Since the <code>flushCompleted</code> method does not modify any other state information, concurrent calls to the <code>flushCompleted</code> method are safe. However, there never should be concurrent calls to the <code>flushCompleted</code> method, because the nature of the flusher mechanism makes it physically impossible for two flushes to complete at the same time.


==References==
==References==
{{reflist}}


{{Design Patterns patterns}}
*{{citation
| last = Grand | first = Mark
| title = Patterns in Java, Volume 1: A Catalog of Reusable Design Patterns Illustrated with UML, Second Edition
| year = 2002
| publisher = John Wiley & Sons
| location = Indianapolis, Ind}}.


[[Category:Software design patterns]]
==See also==
[[Category:Articles with example Java code]]
*[[Read and write lock pattern]]
[[Category:Concurrency (computer science)]]
*[[Guarded suspension|Guarded suspension pattern]]


[[Category:Software design patterns]]


{{soft-eng-stub}}
{{compu-prog-stub}}

Revision as of 22:38, 15 July 2023

The balking pattern is a software design pattern that only executes an action on an object when the object is in a particular state. For example, if an object reads ZIP files and a calling method invokes a get method on the object when the ZIP file is not open, the object would "balk" at the request. In the Java programming language, for example, an IllegalStateException might be thrown under these circumstances.

There are some specialists[who?] in this field who consider balking more of an anti-pattern than a design pattern. If an object cannot support its API, it should either limit the API so that the offending call is not available, or so that the call can be made without limitation. It should:

  • Be created in a "sane state";[further explanation needed]
  • not make itself available until it is in a sane state;
  • become a facade and answer back an object that is in a sane state.

Usage

Objects that use this pattern are generally only in a state that is prone to balking temporarily but for an unknown amount of time.[citation needed] If objects are to remain in a state which is prone to balking for a known, finite period of time, then the guarded suspension pattern may be preferred.

Implementation

Below is a general, simple example for an implementation of the balking pattern.[1] As demonstrated by the definition above, notice how the "synchronized" line is utilized. If there are multiple calls to the job method, only one will proceed while the other calls will return with nothing. Another thing to note is the jobCompleted() method. The reason it is synchronized is because the only way to guarantee another thread will see a change to a field is to synchronize all access to it. Actually, since it is a boolean variable, it could be left not explicitly synchronized, only declared volatile - to guarantee that the other thread will not read an obsolete cached value.

public class Example {
    private boolean jobInProgress = false;

    public void job() {
        synchronized(this) {
            if (jobInProgress) {
                return;
            }
            jobInProgress = true;
        }
        // Code to execute job goes here
        // ...
        jobCompleted();
    }

    void jobCompleted() {
        synchronized(this) {
            jobInProgress = false;
        }
    }
}

See also

References

  1. ^ Grand, Mark (2002). Patterns in Java, Volume 1: A Catalog of Reusable Design Patterns Illustrated with UML, Second Edition. Indianapolis, Ind: John Wiley & Sons.