Sunday, May 26, 2013

Bikeshedding in Dart

‹prev | My Chain | next›

I am still not sold on my one-class-per-dialog approach to the full-screen ICE Code Editor. I am developing in a branch, so no harm done if I abandon the approach. Still, I feel like some change has to be made as, even at this relatively early stage, the Full class is getting unwieldy.

With the new one-class-per-dialog approach, I am able to build the menu like:
class Full {
  // ...
  _showMainMenu() {
    var menu = new Element.html('<ul class=ice-menu>');
    el.children.add(menu);

    menu.children
      ..add(new OpenDialog(this).el)
      ..add(new NewProjectDialog(this).el)
      ..add(new RenameDialog(this).el)
      ..add(new CopyDialog(this).el)
      ..add(new SaveMenu(this).el)
      ..add(new ShareDialog(this).el)
      ..add(new RemoveDialog(this).el)
      ..add(new DownloadDialog(this).el)
      ..add(new HelpDialog(this).el);
  }
}
That is an improvement over the previous approach, primarily because the dialog code (the el, the dialog HTML, and the associated dialog actions) was all in this same Full class as a long series of private methods. Still...

This is probably bikeshedding, but the new, this and el stand out thanks to their repetitiveness. I could try a Dart factory constructor for each (e.g. new OpenDialog.el(this), but that would not help with the new or the this and probably would not help all that much with the .el.

I think about library global methods, but this would only leave me with something along the lines of:

    menu.children
      ..add(openDialogElement(this))
      ..add(newProjectDialogElement(this))
      ..add(renameDialogElement(this))
      ..add(copyDialogElement(this))
      ..add(saveMenuElement(this))
      ..add(shareDialogElement(this))
      ..add(removeDialogElement(this))
      ..add(downloadDialogElement(this))
      ..add(helpDialogElement(this));
There is still repetition of (this) and, to a lesser extent, Element.

So I switch to private methods in Full:
class Full {
  // ...
  _showMainMenu() {
    var menu = new Element.html('<ul class=ice-menu>');
    el.children.add(menu);

    menu.children
      ..add(_openDialog)
      ..add(_newProjectDialog)
      ..add(_renameDialog)
      ..add(_copyDialog)
      ..add(_saveMenu)
      ..add(_shareDialog)
      ..add(_removeDialog)
      ..add(_downloadDialog)
      ..add(_helpDialog);
  }

  get _openDialog=> new OpenDialog(this).el;
  get _newProjectDialog=> new NewProjectDialog(this).el;
  get _renameDialog=> new RenameDialog(this).el;
  get _copyDialog=> new CopyDialog(this).el;
  get _saveMenu=> new SaveMenu(this).el;
  get _shareDialog=> new ShareDialog(this).el;
  get _removeDialog=> new RemoveDialog(this).el;
  get _downloadDialog=> new DownloadDialog(this).el;
  get _helpDialog=> new HelpDialog(this).el;
}
That I like. I move the repetition out of the main flow of the code, leaving the main menu code nice and readable. In the end, I extracted each of those dialog classes out from a series of private methods only to bring them back. Still, better a one-line private method than dozens of lines for each dialog.

Sometimes bikeshedding pays off. If only there was a way to tell when bikeshedding was likely to be worthwhile...

Day #763

No comments:

Post a Comment