←Older revision | Revision as of 15:27, 2 February 2009 | ||
Line 1: | Line 1: | ||
- | Often when reasoning about [[APIDesignPatterns:Exceptions|exceptions]], they are thought to be somewhat special, not really full featured classes. At least many coding practices advice to not use them in | + | Often when reasoning about [[APIDesignPatterns:Exceptions|exceptions]], they are thought to be somewhat special, not really full featured classes. At least many coding practices advice to not use them in situations where regular objects would be more than appropriate. As a result developers often do not think about using [[ExceptionExtensibility|inheritance]] or other object oriented aspects when dealing with [[APIDesignPatterns:Exceptions|exceptions]]. Sometimes this is justified, sometimes it can be too restricting. In [[Java]], [[APIDesignPatterns:Exceptions|exceptions]] are just like any regular class and this can be sometimes used to achieve surprising results. |
All developers think about exceptions as something that can be thrown and caught. Some know that it is useful to call exceptions' [[GettersAndSetters|getters]] to get more info about the failure represented by the exception. However only few explore design style where exceptions also contain [[GettersAndSetters|setters]] or other mutable methods. Not that it would make sense to modify state of the exception itself, as that is short living object, however the exception can serve as a bridge to some internal longer living object and can be its interface allowing changes to its state. | All developers think about exceptions as something that can be thrown and caught. Some know that it is useful to call exceptions' [[GettersAndSetters|getters]] to get more info about the failure represented by the exception. However only few explore design style where exceptions also contain [[GettersAndSetters|setters]] or other mutable methods. Not that it would make sense to modify state of the exception itself, as that is short living object, however the exception can serve as a bridge to some internal longer living object and can be its interface allowing changes to its state. | ||
- | This imperative can be used to implement '''Try/Catch/Redo''' [[APIDesignPatterns|pattern]]. Imagine that some code deep inside of a set of I/O operations cannot proceed without asking a question. For example the [[NetBeans]] version control modules may need to ask the user whether file shall be ''locked'' before allowing its content to be changed. | + | This imperative style can be used to implement '''Try/Catch/Redo''' [[APIDesignPatterns|pattern]]. Imagine that some code deep inside of a set of I/O operations cannot proceed without asking a question. For example the [[NetBeans]] version control modules may need to ask the user whether file shall be ''locked'' before allowing its content to be changed. Showing dialog by itself is big ''no-no'' for low level I/O libraries as it often leads to [[deadlock]]s when fighting for the shared screen. Instead imagine that there is a special [[ExceptionExtensibility|extended]] '''IOException''': |
<source lang="java" snippet="trycatchredo.UserQuestionException"/> | <source lang="java" snippet="trycatchredo.UserQuestionException"/> | ||
Line 15: | Line 15: | ||
<source lang="java" snippet="trycatchredo.SaveActionWithQuery"/> | <source lang="java" snippet="trycatchredo.SaveActionWithQuery"/> | ||
- | The '''confirm''' method is the callback to the internals of the '''URLConnection''' provider, like the [[NetBeans]] version control modules. The '''confirm''' method can change the internal state, just like in simple ''stream'' example: | + | The '''confirm''' method is the callback to the internals of the '''URLConnection''' provider, like the [[NetBeans]] version control modules. The '''confirm''' method can change the internal state, just like in this simple ''stream'' example: |
<source lang="java" snippet="trycatchredo.stream"/> | <source lang="java" snippet="trycatchredo.stream"/> | ||
Line 25: | Line 25: | ||
Some may say that exceptions are not suitable for regular code flow control and as such using the [[TryCatchRedo]] is more a misuse than a regular [[APIDesignPatterns|design pattern]], however this all depends on the frequency. | Some may say that exceptions are not suitable for regular code flow control and as such using the [[TryCatchRedo]] is more a misuse than a regular [[APIDesignPatterns|design pattern]], however this all depends on the frequency. | ||
- | If the '''UserQuestionException''' is used in 99% of cases, by | + | If the '''UserQuestionException''' is used in 99% of cases, by majority of users, then this pattern is definitely not suitable. Calling once, at the ''try'' round, catching the exception and calling again is ridiculously complex. On the other hand if 99% of usages are OK with catching plain '''IOException''' then this pattern is a nice example of making simple things easy and complex possible. To implement this kind of communication without use of exception would create quite rich [[API]] - overly complex for those 99% of its users. |
- | Actually this is nice example of a [[Teleinterface]], a ''bottleneck'' [[API]], based on simplistic assumptions, which allows rich communication between the [[API]] user and provider that both decide to understand the enhanced '''UserQuestionException'''. | + | Actually this is nice example of a [[Teleinterface]], a ''bottleneck'' [[API]], based on simplistic assumptions, which allows rich communication between the [[API]] user and provider that both decide to understand the enhanced '''UserQuestionException'''. The basic ''URL'' [[API]] does not even know that the enhanced communication is going on. Neither 99% of its users. Still, such exception can be teleported from the [[API]] provider to the [[API]] client if necessary. |
+ | <comments/> | ||
[[Category:APIDesignPatterns]] | [[Category:APIDesignPatterns]] | ||
[[Category:APIDesignPatterns:Exceptions]] | [[Category:APIDesignPatterns:Exceptions]] |