dispose pattern
   HOME

TheInfoList



OR:

In
object-oriented programming Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects", which can contain data and code. The data is in the form of fields (often known as attributes or ''properties''), and the code is in the form of ...
, the dispose pattern is a
design pattern A design pattern is the re-usable form of a solution to a design problem. The idea was introduced by the architect Christopher Alexander and has been adapted for various other disciplines, particularly software engineering. The " Gang of Four" b ...
for
resource management In organizational studies, resource management is the efficient and effective development of an organization's resources when they are needed. Such resources may include the financial resources, inventory, human skills, production resources, or i ...
. In this pattern, a
resource Resource refers to all the materials available in our environment which are technologically accessible, economically feasible and culturally sustainable and help us to satisfy our needs and wants. Resources can broadly be classified upon their ...
is held by an
object Object may refer to: General meanings * Object (philosophy), a thing, being, or concept ** Object (abstract), an object which does not exist at any particular time or place ** Physical object, an identifiable collection of matter * Goal, an ...
, and released by calling a conventional
method Method ( grc, μέθοδος, methodos) literally means a pursuit of knowledge, investigation, mode of prosecuting such inquiry, or system. In recent centuries it more often means a prescribed process for completing a task. It may refer to: *Scien ...
– usually called close, dispose, free, release depending on the language – which releases any resources the object is holding onto. Many
programming language A programming language is a system of notation for writing computer programs. Most programming languages are text-based formal languages, but they may also be graphical. They are a kind of computer language. The description of a programming ...
s offer
language construct In computer programming, a language construct is a syntactically allowable part of a program that may be formed from one or more lexical tokens in accordance with the rules of the programming language. The term "language construct" is often used ...
s to avoid having to call the dispose method explicitly in common situations. The dispose pattern is primarily used in languages whose
runtime environment In computer programming, a runtime system or runtime environment is a sub-system that exists both in the computer where a program is created, as well as in the computers where the program is intended to be run. The name comes from the compile t ...
have
automatic garbage collection In computer science, garbage collection (GC) is a form of automatic memory management. The ''garbage collector'' attempts to reclaim memory which was allocated by the program, but is no longer referenced; such memory is called '' garbage''. ...
(see motivation below).


Motivation


Wrapping resources in objects

Wrapping resources in objects is the object-oriented form of encapsulation, and underlies the dispose pattern. Resources are typically represented by
handles A handle is a part of, or attachment to, an object that allows it to be grasped and manipulated by hand. The design of each type of handle involves substantial ergonomic issues, even where these are dealt with intuitively or by following t ...
(abstract references), concretely usually integers, which are used to communicate with an external system that provides the resource. For example, files are provided by the
operating system An operating system (OS) is system software that manages computer hardware, software resources, and provides common services for computer programs. Time-sharing operating systems schedule tasks for efficient use of the system and may also in ...
(specifically the
file system In computing, file system or filesystem (often abbreviated to fs) is a method and data structure that the operating system uses to control how data is stored and retrieved. Without a file system, data placed in a storage medium would be one larg ...
), which in many systems represents open files with a file descriptor (an integer representing the file). These handles can be used directly, by storing the value in a variable and passing it as an argument to functions that use the resource. However, it is frequently useful to abstract from the handle itself (for example, if different operating systems represent files differently), and to store additional auxiliary data with the handle, so handles can be stored as a field in a record, along with other data; if this in an
opaque data type In computer science, an opaque data type is a data type whose concrete data structure is not defined in an interface. This enforces information hiding, since its values can only be manipulated by calling subroutines that have access to the missing ...
, then this provides
information hiding In computer science, information hiding is the principle of segregation of the ''design decisions'' in a computer program that are most likely to change, thus protecting other parts of the program from extensive modification if the design decisio ...
and the user is abstracted from the actual representation. For example, in
C file input/output The C programming language provides many standard library functions for file input and output. These functions make up the bulk of the C standard library header . The functionality descends from a "portable I/O package" written by Mike Lesk a ...
, files are represented by objects of the FILE type (confusingly called "
file handle In Unix and Unix-like computer operating systems, a file descriptor (FD, less frequently fildes) is a process-unique identifier ( handle) for a file or other input/output resource, such as a pipe or network socket. File descriptors typically hav ...
s": these are a language-level abstraction), which stores an (operating system) handle to the file (such as a file descriptor), together with auxiliary information like I/O mode (reading, writing) and position in the stream. These objects are created by calling fopen (in object-oriented terms, a constructor), which acquires the resource and returns a pointer to it; the resource is released by calling fclose on a pointer to the FILE object. In code: FILE *f = fopen(filename, mode); // Do something with f. fclose(f); Note that fclose is a function with a FILE * parameter. In object-oriented programming, this is instead an
instance method A method in object-oriented programming (OOP) is a procedure associated with a message and an object. An object consists of ''state data'' and ''behavior''; these compose an ''interface'', which specifies how the object may be utilized by any ...
on a file object, as in Python: f = open(filename) # Do something with f. f.close() This is precisely the dispose pattern, and only differs in syntax and code structure from traditional file opening and closing. Other resources can be managed in exactly the same way: being acquired in a constructor or factory, and released by an explicit close or dispose method.


Prompt release

The fundamental problem that freeing resources aims to solve is that resources are expensive (for example, there may be a limit on the number of open files), and thus should be released promptly. Further, some finalization work is sometimes needed, particularly for I/O, such as flushing buffers to ensure that all data is actually written. If a resource is unlimited or effectively unlimited, and no explicit finalization is necessary, it is not important to release it, and in fact short-lived programs often do not explicitly release resources: due to short run time, they are unlikely to exhaust resources, and they rely on the
runtime system In computer programming, a runtime system or runtime environment is a sub-system that exists both in the computer where a program is created, as well as in the computers where the program is intended to be run. The name comes from the compile t ...
or
operating system An operating system (OS) is system software that manages computer hardware, software resources, and provides common services for computer programs. Time-sharing operating systems schedule tasks for efficient use of the system and may also in ...
to do any finalization. However, in general resources must be managed (particularly for long-lived programs, programs that use many resources, or for safety, to ensure that data is written out). Explicit disposal means that resource finalization and release is deterministic and prompt: the dispose method does not complete until these are done. An alternative to requiring explicit disposal is to tie resource management to object lifetime: resources are acquired during object creation, and released during
object destruction In object-oriented programming (OOP), the object lifetime (or life cycle) of an object is the time between an object's creation and its destruction. Rules for object lifetime vary significantly between languages, in some cases between implementa ...
. This approach is known as the Resource Acquisition Is Initialization (RAII) idiom, and is used in languages with deterministic memory management (e.g.
C++ C++ (pronounced "C plus plus") is a high-level general-purpose programming language created by Danish computer scientist Bjarne Stroustrup as an extension of the C programming language, or "C with Classes". The language has expanded significan ...
). In this case, in the example above, the resource is acquired when the file object is created, and when the scope of the variable f is exited, the file object that f refers to is destroyed, and as part of this, the resource is released. RAII relies on object lifetime being deterministic; however, with automatic memory management, object lifetime is not a concern of the programmer: objects are destroyed at some point after they are no longer used, but ''when'' is abstracted. Indeed, lifetime is often not deterministic, though it may be, notably if reference counting is used. Indeed, in some cases there is no guarantee that objects will ''ever'' be finalized: when the program terminates, it may not finalize the objects, and instead just let the operating system reclaim memory; if finalization is required (e.g., to flush buffers), data loss can occur. Thus by not coupling resource management to object lifetime, the dispose pattern allows ''resources'' to be released promptly, while giving implementation flexibility for memory management. The cost of this is that resources must be managed manually, which can be tedious and error-prone.


Early exit

A key problem with the dispose pattern is that if the dispose method is not called, the resource is leaked. A common cause of this is early exit from a function, due to an early return or exception. For example: def func(filename): f = open(filename) if a: return x f.close() return y If the function returns at the first return, the file is never closed and the resource is leaked. def func(filename): f = open(filename) g(f) # Do something with f that may raise an exception. f.close() If the intervening code raises an exception, the function exits early and the file is never closed, so the resource is leaked. Both of these can be handled by a try...finally construct, which ensures that the finally clause is always executed on exit: def func(filename): try: f = open(filename) # Do something. finally: f.close() More generically: Resource resource = getResource(); try finally The try...finally construct is necessary for proper
exception safety Exception safety is the state of code working correctly when exceptions are thrown. To aid in ensuring exception safety, C++ standard library developers have devised a set of ''exception safety levels'', contractual guarantees of the behavior of a ...
, since the finally block enables execution of cleanup logic regardless of if an exception is thrown or not in the try block. One disadvantage of this approach is that it requires the programmer to explicitly add cleanup code in a finally block. This leads to code size bloat, and failure to do so will lead to resource leakage in the program.


Language constructs

To make the safe use of the dispose pattern less verbose, several languages have some kind of built-in support for resources held and released in the same block of code. The C# language features the using statement that automatically calls the Dispose method on an object that implements the IDisposable
interface Interface or interfacing may refer to: Academic journals * ''Interface'' (journal), by the Electrochemical Society * '' Interface, Journal of Applied Linguistics'', now merged with ''ITL International Journal of Applied Linguistics'' * '' Int ...
: using (Resource resource = GetResource()) which is equal to: Resource resource = GetResource() try finally Similarly, the
Python Python may refer to: Snakes * Pythonidae, a family of nonvenomous snakes found in Africa, Asia, and Australia ** ''Python'' (genus), a genus of Pythonidae found in Africa and Asia * Python (mythology), a mythical serpent Computing * Python (pro ...
language has a with statement that can be used to similar effect with a ''context manager'' object. The ''context manager protocol'' requires implementing __enter__ and __exit__ methods which get automatically called by the with statement construct, to prevent duplication of code that would otherwise occur with the try/finally pattern. with resource_context_manager() as resource: # Perform actions with the resource. ... # Perform other actions where the resource is guaranteed to be deallocated. ... The
Java Java (; id, Jawa, ; jv, ꦗꦮ; su, ) is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea to the north. With a population of 151.6 million people, Java is the world's List ...
language introduced a new syntax called try-with-resources in Java version 7.Oracle Java tutorial
The try-with-resources Statement
/ref> It can be used on objects that implement the AutoCloseable interface (that defines method close()): try (OutputStream x = new OutputStream(...)) catch (IOException ex) // try


Problems

Beyond the key problem of correct resource management in the presence of returns and exceptions, and heap-based resource management (disposing objects in a different scope from where they are created), there are many further complexities associated with the dispose pattern. These problems are largely avoided by RAII. However, in common simple use these complexities do not arise: acquire a single resource, do something with it, automatically release it. A fundamental problem is that having a resource is no longer a
class invariant In computer programming, specifically object-oriented programming, a class invariant (or type invariant) is an invariant used for constraining objects of a class. Methods of the class should preserve the invariant. The class invariant constrain ...
(the resource is held from object creation until it is disposed, but the object is still live at this point), so the resource may not be available when the object tries to use it, for example trying to read from a closed file. This means that all methods on the object that use the resource potentially fail, concretely usually by returning an error or raising an exception. In practice this is minor, as use of resources can usually fail for other reasons as well (for example, trying to read past the end of a file), so these methods already might fail, and not having a resource just adds another possible failure. A standard way to implement this is to add a boolean field to the object, called disposed, which is set to true by dispose, and checked by a guard clause to all methods (that use the resource), raising an exception (such as ObjectDisposedException in .NET) if the object has been disposed. Further, it is possible to call dispose on an object more than once. While this may indicate a programming error (each object holding a resource must be disposed ''exactly'' once), it is simpler, more robust, and thus usually preferable for dispose to be
idempotent Idempotence (, ) is the property of certain operations in mathematics and computer science whereby they can be applied multiple times without changing the result beyond the initial application. The concept of idempotence arises in a number of pl ...
(meaning "calling multiple times is the same as calling once"). This is easily implemented by using the same boolean disposed field and checking it in a guard clause at the start of dispose, in that case returning immediately, rather than raising an exception. Java distinguishes disposable types (those that implemen
AutoCloseable
from disposable types where dispose is idempotent (the subtyp

. Disposal in the presence of inheritance and composition of objects that hold resources have analogous problems to destruction/finalization (via destructors or finalizers). Further, since the dispose pattern usually does not have language support for this, boilerplate code is necessary. Firstly, if a derived class overrides a dispose method in the base class, the overriding method in the derived class generally needs to call the dispose method in the base class, in order to properly release resources held in the base. Secondly, if an object has a "has a" relationship with another object that holds a resource (i.e., if an object indirectly uses a resource through another object that directly uses a resource), should the indirectly using object be disposable? This corresponds to whether the relationship is ''owning'' (
object composition In computer science, object composition and object aggregation are closely related ways to combine objects or data types into more complex ones. In conversation the distinction between composition and aggregation is often ignored. Common kind ...
) or ''viewing'' (
object aggregation In computer science, object composition and object aggregation are closely related ways to combine objects or data types into more complex ones. In conversation the distinction between composition and aggregation is often ignored. Common kind ...
), or even just ''communicating'' (
association Association may refer to: *Club (organization), an association of two or more people united by a common interest or goal *Trade association, an organization founded and funded by businesses that operate in a specific industry *Voluntary associatio ...
), and both conventions are found (indirect user is responsible for the resource or is not responsible). If the indirect use is responsible for the resource, it must be disposable, and dispose the owned objects when it is disposed (analogous to destroying or finalizing owned objects). Composition (owning) provides encapsulation (only the object that is used needs to be tracked), but at the cost of considerable complexity when there are further relationships between objects, while aggregation (viewing) is considerably simpler, at the cost of lacking encapsulation. In .NET, convention is to only have direct user of resources be responsible: "You should implement IDisposable only if your type uses unmanaged resources directly." See
resource management In organizational studies, resource management is the efficient and effective development of an organization's resources when they are needed. Such resources may include the financial resources, inventory, human skills, production resources, or i ...
for details, and further examples.


See also

* Object lifetime * Resource Acquisition Is Initialization (RAII)


Notes


References

{{reflist


Further reading

* Microsoft Developer Network
Dispose Pattern
Object-oriented programming Memory management Software design patterns