How much should the client know about the implementation of the chain of responsibility pattern? I have reworked my spreadsheet cell formatting example to the point that I am quite satisfied with the code organization and how it responds:

What leaves me slightly less satisfied is how much the Dart constructing code needs to know about the underlying implementation. Currently, I have it constructing the individual links in the chain and assigning those links:
var textFormat = new TextFormatter();
var dateFormat = new DateFormatter(textFormat);
var numberFormat = new NumberFormatter(dateFormat);
I do not think it too horrible that the constructing code needs to know about the individual formatters—especially since it needs to know how to remove some of them in response to checkbox changes. What bugs me here is the same thing that has bugged me about other examples that I have built—the requirement that the constructing code know which link is first, which link has to be constructed first, and with which links each can and should link. That is, the text-formatter is the default link, so it needs to be last in the chain, but it has to be constructed first so that the second-to-last link can point to it. It is also not a good idea to remove the text-formatter (even though I have a checkbox in the UI) because it is the default cell formatter. Lastly, I find it awkward to tell the on-change listener to number-format cells when establishing the request handler:
container.onChange.listen(numberFormat);
Even though it looks like I am asking for number formatting, I am really asking for something in the cell formatting chain to handle the request—number format just happens to be the first.In some (most?) implementations of the chain of responsibility this might actually be OK or desired organization. In this case, I think a facade wants to be in front of this complexity. So I define
CellFormatter
such that it declares the individual link components:class CellFormatter { var _numberFormat = new NumberFormatter(); var _dateFormat = new DateFormatter(); var _textFormat = new TextFormatter(); var first; // ... }I also declare a pointer to the first cell-formatting object so that I know where to start requests and can easily update it. In the constructor, I then establish the links in the chain and initially set
first
:class CellFormatter { // ... CellFormatter() { _numberFormat.nextHandler = _dateFormat; _dateFormat.nextHandler = _textFormat; first = _numberFormat; } // ... }The
call()
method is then simple enough—I send the event request onto the call()
method of the first link in the chain:class CellFormatter { // ... void call(Event e) { first.call(e); } // ... }And, as mentioned, it is easy to manipulate the chain with methods like
ignore()
and obey()
. A simple implementation for the number formatter could be:class CellFormatter { // ... void ignore(String format) { if (format == 'number') first = _dateFormat; // ... } void obey(String format) { if (format == 'number') first = _numberFormat; // ... } }I feel more comfortable putting this knowledge in a class than I would in the main code. At least for this example, this seems like too much maintenance to mingle with other code.
This does lead to some significant improvements in the main code. Obviously, it is much simpler to instantiate one object instead of three (and to omit the linking):
var cellFormat = new CellFormatter();
I also get the benefit of an easier to read (and hence easier to maintain) assignment of the cell-formatter: container.onChange.listen(cellFormat);
This one-liner reads nicely and has low cognitive requirements: when the spreadsheet container sees changes, it cell-formats the source elements. No worry about the chain or the first element in the chain. Formatting is done by the cell formatter. Simple!(see last night's post for why
cellFormat
behave like a function here)The nicest win in this approach may be in the code that ignores/obeys formatters. Previously, when ignoring the number formatter, I had to obtain a subscription from the initial listener so that I could then cancel it and start a new listener with the second link in the chain:
var subscription= container.onChange.listen(numberFormat);
query('#no-numbers').onChange.listen((e){
var el = e.target;
if (el.checked) {
subscription.cancel();
subscription = c.stream.listen(dateFormat);
}
// ...
});
Now that CellFormatter
internally maintains a reference to the first
item in the chain, I no longer need to worry about the stream subscription sending to the wrong first element. The resulting code is mercifully free from subscription code, only obeying or ignoring links as requested:
container.onChange.listen(cellFormat);
query('#no-numbers').onChange.listen((e){
var el = e.target;
if (el.checked) {
cellFormat.ignore('number');
}
// ...
});
That seems a nice improvement.Overall, I am very happy with the improvement in the code as a results of this approach. I have yet to examine it in depth, but I believe this is likely a facade pattern as it hides some of the underlying complexity of the chain of responsibility from the calling context. Regardless of what it is called, I very much like it!
This seems a nice stopping point for my research into the chain of responsibility. Up next, who knows?
Play with the code on DartPad: https://dartpad.dartlang.org/adf7e28a00eba10491e9.
Day #102
NICE for giving a chance to share ideas
ReplyDeletehttp://www.interretakazino.net/
http://www.retafutbala.net/
http://www.retavetludejo.org/
http://www.bisnisholic.web.id/
http://www.bolabonanza.com/
Such an amazing and helpful post this is
ReplyDeletehttp://www.giocodazzardo.org/
http://www.sitiodejuego.com/
http://www.daftarmerekdunia.web.id/
http://www.daftarpresidendunia.web.id/
http://www.sejarahdunia.web.id/
thanks for the quality details
ReplyDeletehttp://www.daftarpeninggalandunia.web.id/ http://www.optimuseuludum.com/
http://www.sakkagyanburusaito.com/
http://www.shinraidekiru.com/
http://www.oszukujehazard.com/
We are really grateful for your blog post. You will find a lot of approaches after visiting your post.
ReplyDeletehttp://www.onrainpoka.com/
http://www.onrainsakka.com/
https://www.futtoborushiti.com/
https://www.debestegoksite.com/
http://www.bestevoetbalgokken.com/
Thanks for sharing, nice post, Post really provice useful information
ReplyDeletehttp://www.stronaoszusta.com/
http://www.stronazgrami.com/
http://www.umegliuagente.com/
https://www.watashitachiha.net/
https://www.dracobetfraudator.com/
congratulations
ReplyDeletehttp://www.ecogaudit.com/
http://www.aleaballsreliable.com/
http://www.optimemitterentpiscis.com/
http://www.optimusonline.net/
http://www.kumpulan-marveldunia.web.id/
Thank you for your article that is very useful and provides complete information for information seekers in the world.
ReplyDeletejoker123
agen joker123
bandar joker123
daftar joker123
login joker123
download joker123
slot joker123
MY HOMEPAGE1
ReplyDeleteMY HOMEPAGE2
MY HOMEPAGE3
MY HOMEPAGE4
MY HOMEPAGE5
google 792
ReplyDeletegoogle 793
google 794
google 795
google 3118
ReplyDeletegoogle 3119
google 3120
google 3121
google 3122
google 3123
google 924
ReplyDeletegoogle 925
google 926
google 927
google 928
google 929
Nagaqq Yang Merupakan Agen Bandarq terbaik , Domino 99, Dan Bandar Poker Online Terpercaya di asia hadir untuk anda semua dengan permainan permainan menarik dan bonus menarik untuk anda semua
ReplyDeleteBonus yang diberikan NagaQQ :
* Bonus rollingan 0.5%,setiap senin di bagikannya
* Bonus Refferal 10% + 10%,seumur hidup
* Bonus Jackpot, yang dapat anda dapatkan dengan mudah
* Minimal Depo 15.000
* Minimal WD 20.000
* Deposit via Pulsa TELKOMSEL
* 6 JENIS BANK ( BCA , BNI, BRI , MANDIRI , CIMB , DANAMON )
Memegang Gelar atau title sebagai AGEN POKER ONLINE Terbaik di masanya
Games Yang di Hadirkan NagaQQ :
* Poker Online
* BandarQ
* Domino99
* Bandar Poker
* Bandar66
* Sakong
* Capsa Susun
* AduQ
* Perang Bacarrat
* Perang Dadu (New Game)
Info Lebih lanjut Kunjungi :
Website : NAGAQQ
Facebook : NagaQQ official
WHATSAPP : +855977509035
Line : Cs_nagaQQ
TELEGRAM :+855967014811
BACA JUGA BLOGSPORT KAMI YANG LAIN:
Winner NagaQQ
Daftar NagaQQ
nagaqq
google 4142
ReplyDeletegoogle 4143
google 4144
google 4145
google 4146
google 3496
ReplyDeletegoogle 3497
google 3498
google 3499
google 3500
google 3501
Great Article. Thanks for posting.
ReplyDeleteabout BJC Carpet Cleaning Jersey City
Sodium metabisulfite is an inorganic compound comprising sodium, sulfur, and oxygen. The sodium metabisulfite market can be segmented into food preservatives, wine making and distilleries, textiles, pulp & paper industry, chemicals and pharmaceuticals, and others.
ReplyDeleteAlso read: acetic anhydride market | Tobacco Market
Nice Blog.
ReplyDeleteGlobal smart grid data analytics market will reach $4,664.2 million by 2027, growing by 11.8% annually over 2020-2027
St. Louis Best Mobile Mechanic
ReplyDeleteBest Mobile Mechanic
brake replacement and repair
used car inspection
Best mobile mechanic in Kansas City
ReplyDeletelocal repair shop
on site vehicle repair
used car inspection
Kannin Law Firm
ReplyDeletepersonal injury
criminal defence
Criminal Defense Lawyer
Anesthesia Malpractice, Birth Injuries, Hospital Malpractice, Including Failure to Prevent Falls, Delays and Failures to Diagnose Spinal-Cord Compression, Delays and Failures to Diagnose Cancer
ReplyDeleteSebelum anda membaca lebih jauh lagi, terlebih dahulu lakukan pendaftaran dan mendapatkan akun ID Judi Slot Online untuk bermain dan mempraktikan permainan mesin slot yang akan kami berikan kepada anda hari ini.
ReplyDeleteCoba buka juga tautan dibawah ini ya teman-teman :
Situs Slot rjoker123.net
Agen Judi Slot rjoker388.net
Daftar Slot rjoker128.net
Login Slot rjoker123.org
Situs ini sangat baik dan saya sangat suka membacanya. Meski begitu kami juga ada beberapa artikel terbaik buat kalian semua.
ReplyDeleteAgen Poker 9Gaming
9Gaming Poker
Agen 9Gaming