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/
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/
congratulations
ReplyDeletehttp://www.ecogaudit.com/
http://www.aleaballsreliable.com/
http://www.optimemitterentpiscis.com/
http://www.optimusonline.net/
http://www.kumpulan-marveldunia.web.id/
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
Sebelum 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
포천출장샵
ReplyDelete양주출장샵
의정부출장샵
남양주출장샵
구리출장샵
ReplyDeletehotmail Founded in 2010 by David Edery and Daniel Cook, Spry Fox specializes in making casual, wholesome games. Its mission statement, as per its website, is: “We want to make the world a happier place and we’re using games to do it.”
Indulge in the exotic flavors of passion with Monster Rabbit, offering the finest Epimedium Honey Dubai. Experience heightened pleasure and vitality with our premium selection, meticulously crafted for your satisfaction. Elevate your intimate moments with Monster Rabbit, the epitome of luxury and sensuality.
ReplyDeleteCMOLDS, a premier app development company in dubai, excels in crafting innovative mobile applications tailored to meet diverse business needs. With a team of seasoned developers and cutting-edge technology, we transform ideas into functional, user-friendly apps that drive growth and engagement. Partner with CMOLDS for custom app solutions that stand out in Dubai's competitive tech landscape.
ReplyDeleteThanks for sharing this. I want hotmail signup api key for intigration in my blog post. Is there anyone who help me in this matter.
ReplyDeleteliteralnie
ReplyDelete