3

オンライン フォーラムの Web クローラーのようなプログラムを書いています。クロールするフォーラムごとに、同じことを行う必要があります。

  1. ログインする
  2. ボードを見つける
  3. 投稿を見つける
  4. 投稿へのパーマリンクを見つける
  5. 投稿者のユーザー名を見つける

これと同じロジックが各フォーラムで発生する必要がありますが、各フォーラムの実装は異なります。たとえば、各ログイン フォームの入力はフォーラムごとに異なります。1 つのフォーラムには「username」という名前のフィールドがあり、もう 1 つのフォーラムには「user」という名前のフィールドがある場合があります。これらのステップの一部には、デフォルトの実装がある場合があります。たとえば、 のデフォルトの実装でloginは何もしません (クロールするために一部のフォーラムにログインする必要がないため)。

私が行ったことは、これらすべてのステップに名前を付けた関数を作成しましたcrawl-forumが、実装は抽象的であり、別の場所に実装されています。私の質問は、これらの実装を使用するための最良の方法は何ですか?crawl-forum

私が試したこと

1) コンフィグマップ

これが私がこれまでに試したことです。crawl-forumという関数に新しい引数を追加しましたconfigs。これは、次のようなマップ データ構造です。

{ :login login-function
  :find-boards find-boards-function
  ...
}

呼び出すコードcrawl-forumは、そのマップの作成を担当します。これについて私が気に入らないのは、コードconfigs全体に渡す必要があることです。crawl-forumどこにでも新しいパラメーターを追加します。また、デフォルトの実装を処理するための不完全でアドホックなコードもあります。

2) マルチメソッド

私はこれについて irc で話しましたが、実際にはポリモーフィックな動作であるため、代わりにマルチメソッドを使用する必要があるという考えを誰かが教えてくれました。それらは次のようになります。

(defn get-site-key [& args] (first args))
(defmulti login get-site-key)
(defmethod login :default [site-key cookie-store] nil)

次に、クライアント コードは外部で独自のマルチメソッドを定義する必要があります。

(defmethod login :forum-1 [site-key cookie-store] (do-something cookie-store))

これについて私が気に入らないのは、 と同じように、を関数configに渡す必要があり、それを内部のあらゆる場所に渡さなければならないことです。また、everyはパラメーターとして独自に戻す必要がありますが、いずれもそれを使用することはありません。これは単にディスパッチを行うために必要な引数です。ただし、完全なマルチメソッドのチュートリアルを見つけるのは非常に難しいので、これを行うよりスマートな方法があれば教えてください.site-keycrawl-forumsite-keydefmethodsite-key

さらに優れた3番目のオプションはありますか?マルチメソッドを使用するより良い方法はありますか? 教えてください、ありがとう。

4

2 に答える 2

1

オプション1を使用します。マップを渡すのが面倒な場合は、いつでも動的変数を使用できます。デフォルトでは、マージを使用することをお勧めします。

(def defaults { ... })
(def site-specific (merge defaults { ...}))
于 2013-05-22T22:26:42.830 に答える
1

使用できますProtocols。これらは、ポリモーフィックな動作をサポートするマルチメソッドの後継です。さらに、Protocol を定義すると、:gen-classネームスペース ディレクティブを使用して Java インターフェイスにコンパイルできます。

理解に役立ついくつかのリンクを次に示します。

ただし、私は単純な実装アプローチに偏っています。機能をマップするフォーラム URL のマップを維持します。つまり、

(def config 
  {"http://forum1.com" {:login login-function1
                          :find-boards find-boards-function1 ... }
   "http://forum2.com" {:login login-function2 
                          :find-boards find-boards-function2 ... }
    ;; etc
   "http://forumN.com" {:login login-functionN
                          :find-boards find-boards-functionN ... }})

その他

(crawl-forum (get config forum-url))

小さなアプリケーションでは、この単純なアプローチに問題はないと思います。インターフェイスとポリモーフィズムは、チーム メンバーが距離と時間で離れている大規模なプロジェクト向けです。

于 2013-05-22T19:44:16.763 に答える