P-Patterns!
From Andrey
Revision as of 05:30, 15 November 2019 Andrey (Talk | contribs) ← Previous diff |
Revision as of 05:37, 15 November 2019 Andrey (Talk | contribs) Next diff → |
||
Line 5: | Line 5: | ||
== Smart Button == | == Smart Button == | ||
- | Suppose you bought a futuristic DVD player - a slick black box with a single tiny hole for the microphone. It does amazing job of recognizing voice commands. To open the drive bay you would say 'Open the drive'. To pause, you would say 'Do pause', and so on. You liked it in the beginning, but unfortunately, you have to always consult product manual because you keep forgetting the exact commands. For example, one day you might say 'Pause' instead of 'Do pause', and it wouldn't react. Finally, you start wanting a more traditional interface - the one with the buttons, so to operate it I wouldn't have to remember commands. With the several buttons, you have complete control over the device and do not have to consult the manual. | + | Suppose you bought a futuristic DVD player - a slick black box with a single tiny hole for the microphone. It does amazing job of recognizing voice commands. To open the drive bay you would say 'Open the drive'. To pause, you would say 'Do pause', and so on. You liked it in the beginning, but unfortunately, you have to always consult the product manual, because you have to memorize exact commands. For example, one day you might say 'Pause' instead of 'Do pause', and it wouldn't react. Finally, you start wanting a more traditional interface - the one with the buttons, so to operate it you wouldn't have to remember commands. With several buttons, you have complete control over the device and do not have to consult the manual! |
- | The pattern is: | + | The design pattern is: |
Expose a generic object in the interface in order to simplify class use. | Expose a generic object in the interface in order to simplify class use. | ||
- | This is the case for exposing an object in the interface. I know that there is opposition for doing so, and even a law ([http://www.ccs.neu.edu/home/lieber/LoD.html Law of Demeter]). However, I choose to say that exposing an object that belongs to a generic, well-known class (in the above case, a button) in the interface provides for simpler, more intuitive designs. Compare this to hiding everything under a monolith interface with a variety of methods. So, if the list of class's methods reads like a laundry list, return it back to the store :) | + | This is the case for exposing an object in the interface. I know that there is opposition for doing so, and even a law ([http://www.ccs.neu.edu/home/lieber/LoD.html Law of Demeter]). However, I choose to say that exposing an object that belongs to a generic, well-known class (in the above case, a button) in the interface provides for simpler, more intuitive designs. Compare this to hiding everything under a monolith interface with a laundry list of methods. |
- | Not being entirely opposed to the Law of Demeter, however I often felt that it stems from assumption that exposing an object results in loss of control, if actions that are performed on the exposed object. While it is true in some OO languages, there are designs and approaches that provide for such control ([[Overriding_in_Owner_Class |Example]]). In the presence of such mechanisms, the Law of Demeter may be less crucial. | + | Not being entirely opposed to the Law of Demeter, however I often felt that it stems from assumption that we couldn't fully control an object after exposing it in the interface. While it is true in some OO languages, there are designs and approaches that provide for such control ([[Overriding_in_Owner_Class |Example]]). In the presence of such mechanisms, the Law of Demeter may be less crucial. |
- | On the other hand, I'm also not entirely for breaking encapsulation and exposing any inner object in class interface. In our example with our DVD player it only makes sense to expose some objects (buttons, indicators) while keeping much other components, the one that really do the job, inside. Therefore, more precisely, we want to only expose very generic control-like objects (buttons, status strings), while keeping implementation-specific parts still hidden from the class user. | + | On the other hand, I'm definetely not advocating for breaking encapsulation and exposing inner objects in class interface. In our example with a DVD player, it only would make sense to expose some objects (buttons, indicators) while keeping others - the one that really do the job - encapsulated. Therefore, more precisely, we want to only expose very generic objects providing for intuitive control, while keeping implementation-specific parts still hidden inside the class. |
== Postponed Validation == | == Postponed Validation == |
Revision as of 05:37, 15 November 2019
Contents |
P-Patterns
Some patterns I came up with.
Smart Button
Suppose you bought a futuristic DVD player - a slick black box with a single tiny hole for the microphone. It does amazing job of recognizing voice commands. To open the drive bay you would say 'Open the drive'. To pause, you would say 'Do pause', and so on. You liked it in the beginning, but unfortunately, you have to always consult the product manual, because you have to memorize exact commands. For example, one day you might say 'Pause' instead of 'Do pause', and it wouldn't react. Finally, you start wanting a more traditional interface - the one with the buttons, so to operate it you wouldn't have to remember commands. With several buttons, you have complete control over the device and do not have to consult the manual!
The design pattern is:
Expose a generic object in the interface in order to simplify class use.
This is the case for exposing an object in the interface. I know that there is opposition for doing so, and even a law (Law of Demeter). However, I choose to say that exposing an object that belongs to a generic, well-known class (in the above case, a button) in the interface provides for simpler, more intuitive designs. Compare this to hiding everything under a monolith interface with a laundry list of methods.
Not being entirely opposed to the Law of Demeter, however I often felt that it stems from assumption that we couldn't fully control an object after exposing it in the interface. While it is true in some OO languages, there are designs and approaches that provide for such control (Example). In the presence of such mechanisms, the Law of Demeter may be less crucial.
On the other hand, I'm definetely not advocating for breaking encapsulation and exposing inner objects in class interface. In our example with a DVD player, it only would make sense to expose some objects (buttons, indicators) while keeping others - the one that really do the job - encapsulated. Therefore, more precisely, we want to only expose very generic objects providing for intuitive control, while keeping implementation-specific parts still hidden inside the class.
Postponed Validation
Say you have a setProperty() method which changes the value of an object field. You typically validate method arguments right in the body of the method; and sometimes you also need a more extensive validation, e.g. if your object is one of a compound type. Such validations may sometimes be taxing on performance in processing-intensive scenarios. Instead, you perform validations in the time of a commit. If a validation rule is broken, perform a rollback. Postponing validations until commit lets you ensure data integrity while maintaining high performance.
Postpone object validation until a checkpoint/commit so that validations do not hinder performance.
One way to implement the postponed validation is Detached Validation. Create a flag in your class to switch validations on and off, and perform a full object validation each time the flag is turned on. While in the 'detached' state (flag is off), skip any validations thus improving performance. Enforce each object to be back to its non-detached (flag on) state before a commit/checkpoint.
Static resolution
Hide a class behind a static interface to improve code brevity and clarity. Instead of creating a Singleton and always calling its getInstance() method, create a class that implements same interface through static methods, and provide one instance of your class as a working horse for that class. The client code which looked like
Logging logging = Logging.getInstance(); logging.error("my message");
becomes this:
Log.error("my message");
where Log is a static-interface class serving as a facade for the Logging class.
Pure Business Objects
Divide model classes into pure business object classes and application-specific implementations inheriting from them. In the model, only deal with pure business object classes, while instantiating only the application-specific implementations for them. Utilize the Bridge design pattern to decouple inheritance graphs of both hierarchies and to separate the model from application-specific behaviors.