Before wrapping up my initial research on the chain of responsibility pattern, I take one last look at the consequences of code that follows it. In particular, I would like to touch on configuration and maintainability tonight.
The example that I currently favor for illustrating the pattern is a set of cell formatting objects for a spreadsheet application:
To auto-format the cells, each formatting object in the chain is given an opportunity to claim responsibility for the content. In this example, a cell with all numbers is converted to a double with two digits after the decimal, a date is converted to ISO 8601 format, and everything else defaults to text.
To test configuration, I add some checkboxes to disable some of the formatters:
The main takeaway from this is that it is possible to easily change the chain of responsibility at runtime. The Dart listener for the no-text formatting checkbox might look like:
query('#no-text').onChange.listen((e){
var el = e.target;
if (el.checked) {
date.nextHandler = null;
}
else {
date.nextHandler = text;
}
});
The date
formatter normally points to the text handler. That is, if the date formatter thinks the current input field is not a date, then it forwards the request onto the text formatter. By ticking this checkbox, the date formatter now thinks that there is no next handler.Thanks to last night's
CellFormatter
base class, this just works:abstract class CellFormatter { CellFormatter nextHandler; void processRequest(Event e) { if (!isCell(e)) return; if (handleRequest(e)) return; if (nextHandler == null) return; nextHandler.processRequest(e); } // ... }With the checkbox ticked, the date formatter no longer has a
nextHandler
so the date formatter simply does nothing. The result in the UI is that a cell that was previously a numeric and was right-aligned retains the alignment because there is no longer a text formatter to reset it:This illustrates another important aspect of the chain of responsibility. It is best to ensure that requests do not just "fall off" the end of the chain like this. Ideally, I ought to have a default handler at the end then resets all styles.
One last thing that I would like to touch on before calling it a day is how robust the pattern is in the face of change. Currently, the first formatter in the chain processes event requests when changes are seen in cells:
container.onChange.listen(number.processRequest);
What if I also wanted to apply changes when clicks are seen inside cells? Well, aside from Dart's lack of an easy means to merge event streams, this is fairly easy to support.I create a
StreamController
object and add events to it whenever there are clicks or changes: var c = new StreamController();
container.onChange.listen(c.add);
container.onClick.listen(c.add);
Then, I hand the first formatter in the chain to this combo-stream: c.stream.listen(number.processRequest);
And that's all there is to it. Now I can force formatting by tabbing to another cell or, if I am feeling impatient, I can click on a cell to format its contents.Nice! That may finish my exploration of the chain of responsibility pattern in Dart (though there could be one more Darty trick to try). I do think this spreadsheet cell example will serve nicely in Design Patterns in Dart. The code is fairly simple, yet still feels like a real example, which is pretty close to ideal. Plus, it serves well when discussing some of the consequences of the pattern!
Play with the code on DartPad: https://dartpad.dartlang.org/08105c648b253f64a47d.
Day #100
MY HOMEPAGE1
ReplyDeleteMY HOMEPAGE2
MY HOMEPAGE3
MY HOMEPAGE4
MY HOMEPAGE5
google 801
ReplyDeletegoogle 802
google 803
google 804
google 805
google 3107
ReplyDeletegoogle 3108
google 3109
google 3110
google 3111
google 3112
google 954
ReplyDeletegoogle 955
google 956
google 957
google 958
google 4153
ReplyDeletegoogle 4154
google 4155
google 4156
google 4157
google 4158
google 3508
ReplyDeletegoogle 3509
google 3510
google 3511
google 3512
Check Hackensack Contractor Service professional services like:
ReplyDeleteinterior remodeling
concrete services
painting services
cabinetry services