私はJS webappクライアントを書いています。ユーザーは、テキスト項目のリスト/ツリー (todo リストやメモなど) を編集できます。jQuery で DOM をよく操作します。
ユーザーは、キーボード (GMail の J/K キーに似ています) を使用してリストを上下に移動し、その他のいくつかの操作を実行できます。これらの操作の多くには、「アップ」/「ダウン」機能があります。
$.fn.moveItemUp = function() {
var prev = this.getPreviousItem();
prev && this.insertBefore(prev);
// there's a bit more code in here, but the idea is pretty simple,
// i.e. move the item up if there's a previous item in the list
}
$.fn.moveItemDown = function() {
var next = this.getNextItem();
next && this.insertAfter(next);
// ....
}
2 つのほぼ同一の関数を持つこのパターンは、私のコードのいくつかの場所で繰り返されます。これは、アイテムのリスト/ツリーにかなり対称的な操作が多数あるためです。
質問:コードの重複を避けるために、これをエレガントにリファクタリングするにはどうすればよいですか?
これまでに思いついた簡単な方法は、.apply() を使用することです...
$.fn.moveItem = function(direction) {
var up = direction === 'up',
sibling = up ? this.getPreviousItem() : this.getNextItem(),
func = up ? $.fn.insertBefore : $.fn.insertAfter;
// ...
if (! sibling) { return false; }
func.apply(this, [ sibling ]);
// ...
};
コードの他の要素の構造で moveUp/moveDown を変更する必要がある場合、メンテナンスが容易になるという利点があります。コードを何度も少し変更する必要がありましたが、常に2か所で行う必要があることを覚えておく必要があります...
しかし、次の理由から、「統合」バージョンには満足していません。
- 実装は単純な moveUp/moveDown よりも複雑であるため、将来的には保守が容易でなくなる可能性があります。シンプルなコードが好きです。これらすべてのパラメーター、三項演算、.apply() は、「上昇」および「下降」するはずのすべての関数のトリック...
- jQuery.fn.* 関数を明示的に参照することが安全かどうかはわかりません (結局のところ、それらは jQuery オブジェクト $('...').* に適用して使用することになっています)。
DOM または同様の構造を使用する場合、これらの「ほぼ同一のコード」の状況をどのように解決しますか?