問題タブ [leaky-abstraction]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
8 に答える
2137 参照

oop - 流暢なインターフェースと漏れやすい抽象化

流暢なインターフェースとは何ですか?これの適切な定義を見つけることはできませんが、私が得たのは、私があまりよく知らない言語(C ++など)での長いコード例だけです。

また、リークのある抽象化とは何ですか?

ありがとう

0 投票する
4 に答える
662 参照

python - Python: if 句のない空でないリストの反復は空になります。なんで?

空でないシーケンスに対するイテレータは、フィルタリングも集計も行わず (sum()など)、何も生成しないのはなぜでしょうか?

簡単な例を考えてみましょう:

これで期待通りの結果が得[('a', 97), ('b', 98), ('c', 99)]られます。

ord(el)ここで、 out を、いくつかのジェネレーターから最初の値を取得する式に交換するだけです(...).next()— 不自然な例を許してください:

これにより が得られ[]ます。ええ、空のリストです。('a',スタッフ)タプルはありません。何もない。

ただし、フィルター処理、集計、削減は行っていません。nフィルタリングや集計を行わないオブジェクトに対するジェネレータ式は、オブジェクトを生成する必要がありnますよね? どうしたの?

0 投票する
2 に答える
757 参照

c# - ORM を使用しない N 層データベース アプリケーションで、UI は表示するデータに必要なものをどのように指定しますか?

ここでポインタと情報を探しています。正しい答えが 1 つもないと思われるので、この CW を作成します。これは C# 用であるため、以下で Linq を参照します。また、長文失礼いたしました。ここで質問を要約させてください。その後、完全な質問が続きます。

概要: UI/BLL/DAL/DB の 4 層アプリケーションで、ユーザー インターフェイスを変更して、より多くの列 (グリッドなど) を表示し、ビジネス ロジック層からデータ アクセス層へのリークを回避するにはどうすればよいでしょうか。表示するデータを取得します (既にデータベースにあると仮定します)。


3(4) 層の階層化されたアプリケーションを想定してみましょう。

  • ユーザー インターフェイス (UI)
  • ビジネス ロジック層 (BLL)
  • データ アクセス層 (DAL)
  • データベース(DB;第4層)

この場合、DAL は SQL ステートメントを作成し、データベースに対して実行してデータを返します。

そのようなレイヤーを「正しく」構築して常に「select *」を実行する唯一の方法はありますか? 私にはそれは大したことではありませんが、なぜ私が疑問に思っているのかを説明させてください.

UI に、有効な雇用記録を持つすべての従業員を表示したいとしましょう。「アクティブ」とは、雇用記録の from-to の日付に今日が含まれていることを意味します (または、ユーザー インターフェイスで設定できる日付も含まれている可能性があります)。

この場合、これらすべての人に電子メールを送信したいとします。そのため、BLL には、同じ人にまだ電子メールを送信していないことを確認するコードがあります。

BLL の場合、最小限のデータが必要です。おそらく、データ アクセス層を呼び出してアクティブな従業員のリストを取得し、次に、送信した電子メールのリストを取得する呼び出しを呼び出します。次に、それらを結合して新しいリストを作成します。おそらく、これはデータ アクセス層の助けを借りて行うことができますが、これは重要ではありません。

重要なことは、ビジネス層にとって必要なデータはそれほど多くないということです。おそらく、両方のリストの各従業員の一意の識別子が必要であり、一致してから、「これらはアクティブで、まだメールを送信していない従業員の一意の識別子です」と言うだけです。次に、ビジネス層が必要とするものだけを取得する SQL ステートメントを構築する DAL コードを構築しますか? すなわち。「SELECT id FROM employees WHERE ...」だけですか?

では、ユーザー インターフェイスはどうすればよいでしょうか。ユーザーにとっては、メールを送信する理由に応じて、より多くの情報を含めることがおそらく最善でしょう。たとえば、基本的な連絡先情報、勤務先の部署、マネージャーの名前などを含めたいと思うかもしれませんが、少なくとも名前と電子メール アドレスの情報を表示することは言うまでもありません。

UI はそのデータをどのように取得しますか? UI に十分なデータを返すように DAL を変更する必要がありますか? BLL を変更して、UI に十分なデータが返されるようにする必要がありますか? DAL から BLL に返されたオブジェクトまたはデータ構造を UI にも送信できる場合、おそらく BLL はあまり変更する必要はありませんが、UI の要件は、通信する必要があるレイヤーを超えてレイヤーに影響を与えます。 . また、2 つの世界が異なるデータ構造で動作する場合は、おそらく両方に変更を加える必要があります。

そして、UI が変更された場合、さらに列を追加してユーザーをさらに支援するには、UI を変更するためにどのくらい深くする必要がありますか? (データがデータベースに既に存在すると仮定しているため、そこで変更する必要はありません。)

出てきた 1 つの提案は、Linq-To-SQL と IQueryable を使用することです。これにより、何 (データの種類など) と理由 (WHERE 句など) を処理する DAL が IQueryable を返した場合、BLL はUI にそれらを返す可能性があり、必要なデータを取得する Linq クエリを作成できます。ユーザー インターフェイス コードは、必要な列を取得できます。IQuerables を使用すると、UI が実際にクエリを実行し、「select new { X, Y, Z }」を使用して必要なものを指定し、必要に応じて他のテーブルに結合できるため、これは機能します。

これは私には面倒に見えます。Linq フロントエンドの背後に隠されている場合でも、UI が SQL コード自体を実行すること。

ただし、これを行うには、BLL または DAL がデータベース接続を閉じることを許可しないようにする必要があります。また、IoC タイプの世界では、DAL サービスは UI コードが望むよりも少し早く破棄される可能性があります。 Linq クエリは、「破棄されたオブジェクトにアクセスできません」という例外で終了する場合があります。

だから私はポインタを探しています。私たちはどれくらい離れていますか?これにどう対処していますか?UI の変更が BLL を介して DAL に漏れるという事実は、非常に悪い解決策だと思いますが、今のところ、改善できるようには見えません。

私たちがどれほど愚かであるか教えてください。私が間違っていることを証明してください。

また、これはレガシー システムであることに注意してください。データベース スキーマの変更はまだ何年も前から行われていないため、「select *」と本質的に同等の処理を行う ORM オブジェクトを使用するソリューションは、実際にはオプションではありません。レイヤーのリスト全体をプルアップしたくない大きなテーブルがいくつかあります。

0 投票する
4 に答える
512 参照

java - 設計上の問題: RMI にはオブジェクトの明示的なエクスポートが必要です

RMI を介して通信する 2 つのアプリケーション、スレーブ サーバー (そのうち複数あります) とマスター サーバーがあります。

優れた抽象設計に従って、マスターと通信するときに RMI を使用していることをスレーブが認識しないようにスレーブを実装したいと思います (たとえば、2 つのアプリを同じ JVM 内で実行できるようにするため)。 :

問題: 上記の行はPROBLEM LINE機能しません。単純にこれを渡すことができないためです (それSlave自体は、応答する aです)。明示的に行う必要があります(または以前にエクスポートした場合) が、それによってクラスが RMI に依存し、設計が壊れます。RemoteMasterUnicastRemoteObject.exportObject(this, 0)toStub(this)Slave

さらに、RMI 依存関係も追加registerSlaveする catch を強制します。RemoteException

これらの問題を解決するために何を提案しますか?

(また、これらのクラスが Remote を実装しなければならないことにも悩まされていますが、抽象化でしか実現できないと思います)

0 投票する
11 に答える
23629 参照

programming-languages - リーク抽象化の意味は?

「リーク抽象化」という用語はどういう意味ですか?(例を挙げて説明してください。私は、単なる理論を理解するのに苦労することがよくあります。)

0 投票する
3 に答える
1205 参照

c++ - 不透明なオブジェクトに整数 ID またはポインターを使用する必要がありますか?

いくつかのグラフィックス API (DirectX9 および DirectX11) の上に抽象化レイヤーを作成しています。ご意見をお聞かせください。

従来、抽象化したい概念ごとに基本クラスを作成していました。
したがって、典型的な OO のやり方では、たとえばクラス Shader と 2 つのサブクラス DX9Shader および DX11Shader を使用します。

テクスチャなどのプロセスを繰り返します...それらをインスタンス化する必要がある場合、現在のグラフィックス API に応じて適切なサブクラスを返す抽象ファクトリがあります。
RAII に従って、返されるポインターは std::shared_ptr にカプセル化されます。

これまでのところうまくいっていますが、私の場合、このアプローチにはいくつかの問題があります。

  1. 両方の API (および将来的には他の API) の機能をカプセル化するパブリック インターフェイスを考え出す必要があります。
  2. 派生クラスは別々の DLL (DX9 用に 1 つ、DX11 用に 1 つなど) に格納されており、クライアントでそれらに shared_ptr を設定するのは呪いです: 終了時にグラフィック DLL がアンロードされ、クライアントにまだ shared_ptr がある場合アンロードされた DLL からのコードの呼び出しが原因で、グラフィックス オブジェクトの 1 つがブーム、クラッシュします。

これにより、私は自分のやり方を再設計するようになりました.リソースへの生のポインターを返すだけで、グラフィックス API をきれいにすることができると思っていましたが、クライアント側にぶら下がっているポインターの問題とインターフェイスの問題がまだあります. COM のような手動参照カウントも考えましたが、それは後退だと思いました (shared_ptr の世界から来て、手動参照カウントは原始的なようです)。

次に、すべてのグラフィックス クラスが整数 ID で表される Humus の作業を見ました (OpenGL と同じように)。新しいオブジェクトを作成すると、その整数 ID のみが返され、ポインターが内部に保存されます。それはすべて完全に不透明です!

抽象化を表すクラス (DX9Shader など) はすべて、唯一のインターフェイスであるデバイス API の背後に隠されています。
テクスチャを設定したい場合は、device->SetTexture(ID) を呼び出すだけで、残りは舞台裏で行われます。

残念なことに、API の隠れた部分が肥大化していること、それを機能させるために必要なボイラー プレート コードがたくさんあること、そして私はすべてを行うクラスのファンではないことです。

アイデア/考えはありますか?

0 投票する
1 に答える
257 参照

clojure - clojure の抽象化とどのように統合するのが最善でしょうか?

ランクに基づいて要素を取得する clojure で順序付きセットを実装しています。これは、4 番目の要素 (セットの順序に従って)、3 番目、または 7 番目の要素をすべて対数時間で取得できることを意味します。

conjget、などの clojure の一般的なメソッド (または「抽象化」) と統合された新しいデータ構造を取得するには、次の方法nthが適しています。

  1. conjたとえば、私のデータ型のプロトコルで実際に実装するか、
  2. Rich Hickeyclojure.lang.IPersistentSetまたはそれに似たインターフェースを実装します。

最初の方法は簡単に思えますが、関数のセマンティクスを台無しにするのも簡単です。2 つ目は、パブリック API の一部になることを意図していないインターフェイスを実装しているように見えます。そのインターフェイス (プロトコル) に関連付けられている実際のメソッドは、紛らわしいほど異なります。たとえば、conj私のセットで実装するには、別の名前の のconsメソッドを実装する必要があるようです。clojure.lang.IPersistentSetこれがどのように機能するかについてのドキュメントはほとんどないようで、このランク付けされたセットを実装する上で大きな課題となっています。

どちらを選ぶべきですか?clojure.lang独自のメソッドまたはインターフェイスのメソッドを実装する必要がありますか? 後者を行う必要がある場合、プロセスをガイドできる優れたドキュメントはどこにありますか?

編集:要素のランクを指定することにより、対数時間で任意の要素を取得(または「削除」)できるセットを作成しようとしていることを明確にしたいと思います(たとえば、「5番目の要素をください、mr.設定。")。私の知る限り、そのようなセットは clojure にはまだ存在しません。

0 投票する
1 に答える
51 参照

c# - その背後に隠されているクラスを知っている場合、Tを返す方法は?

私は T がList<string>(またはList<MyClass>) であることを知っています。この文字列のリストを返すことを可能にするリフレクションまたは何かをどのように見えるべきですか?

背景: Deserialize メソッドは、html データの解析に使用されます。ウェブサイトで使われている独自の myJson.myDeserialize メソッドのようなもので、API はありません。

0 投票する
1 に答える
1213 参照

entity-framework - 汎用リポジトリと漏れやすい抽象化

私はリポジトリパターンを実装しています。これの私の主な理由:

  • 永続化の詳細からクライアント コードを抽象化するには (Entity Framework)
  • テスト容易性をサポートする

汎用リポジトリかどうか?

私が遭遇した問題は、汎用リポジトリが必要かどうかです。メソッドは、特定のクエリを作成するIQueryable<T> Query()手段を呼び出し元のコードに提供します。ここでの問題は、これが漏れやすい抽象化であることです。Entity Framework の仕様がクライアント コードに漏れています。

ここに画像の説明を入力

  • これは単体テストにどのように影響しますか? ICustomerRepositoryこの実装で モックを作成することはできますか?

  • これは私の永続層を一掃することにどのように影響しますか? Azure Storage Tables や NHibernate と同様です。

そうしないとICustomerRepository、 や などの非常に特殊なクエリ メソッドを に実装する必要がGetIsActiveByFirstName()ありGetIsActiveByDistrict()ます。私のリポジトリクラスがさまざまなクエリメソッドでぎゅうぎゅう詰めになるので、これはとても嫌いです。このシステムには数百のモデルがあるため、作成および保守するこれらのメソッドが数百または数千になる可能性があります。