仕事で非常に興味深い状況に遭遇したので、ここで解決策を共有したいと思いました。
一連のデータを処理する必要があると想像してください。そして、このデータセットを扱うには、いくつかの異なる戦略があります。たとえば、S3 からデータのコレクション、ローカル リポジトリ内のサンプル、または入力として渡されるサンプルを取得する方法に関する戦略を作成する必要がありました。
そして、この戦略を決定するのは、リクエストを行う人です:
S3のデータを取得したい。 X 日目の H1 時間と H2 時間の間に生成された、Abobora クライアントからのデータを取得します。これを満たす最後の 3000 データを取得します。
または:
そこにあるサンプル データを 10,000 回コピーして、ストレス テストを実行します。
または:
私はこのディレクトリを持っています。あなたもそれにアクセスできます。そのディレクトリ内のすべてを取得し、サブディレクトリに再帰的に入れます。
そして最後に:
入力にあるこのデータユニットを取得して使用します。
実装方法は?
最初に考えたのは、「Java で入力の形状を定義するにはどうすればよいでしょうか?」
そして私は、プロジェクトにとって非常に重要な最初の結論に達しました: 「ご存知ですか? 形状を定義するつもりはありません。それを処理できる Map
その上、DTO にシェイプを入れていないので、入力を完全に自由に試すことができました。
したがって、概念実証を確立した後、ストレスの多い POC から抜け出し、実際の使用に近いものに進む必要があるという状況に到達します。
私が行っていたサービスはルールを検証することでした。基本的に、ルールを変更するときは、そのルールを取得し、本番アプリケーションで発生したイベントと照合する必要がありました。または、アプリケーションが変更され、バグがなかった場合、同じデータに対する同じルールの決定が同じままであることが期待されます。ここで、同じデータセットを使用する同じルールの決定が変更された場合...そうですね、それは潜在的な問題です。
そこで、ルールのバックテストを実行するにはこのアプリケーションが必要でした。評価用のデータと問題のルールを送信する実際のアプリケーションを実行する必要があります。これの使用法は非常に多様です:
- アプリケーションの更新時に潜在的な逸脱を検証します
- 変更されたルールが同じ動作を維持するかどうかを検証する
- ルールの実行時間の最適化など
- ルールの変更により、予想される意思決定の変更が生じたかどうかを確認します
- アプリケーションの変更により実際に効率が向上したことを検証する
- たとえば、JVMCI を有効にして新しいバージョンの GraalVM を使用すると、実行できるリクエストの数が増加しますか?
そのためには、イベントの起源に関するいくつかの戦略が必要です。
- S3 から実際のデータを取得します
- リポジトリ内のサンプルとしてデータを取得し、複数回コピーします
- ローカルマシン上の特定の場所からデータを取得します
そして、私のルールとは異なる戦略も必要です:
- 入力経由で渡されました
- 高速実行スタブを使用します
- プロダクションルールに基づいたサンプルを使用します
- 私のマシンではこのパスを使用してください
これにどう対処しますか?そうですね、ユーザーにデータを提供してもらいましょう!
戦略のための API
json スキーマについて私がいつも注意を引いていたことを知っていますか?これはこちらです:
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/schema", "$vocabulary": { //... } }
これらのフィールドは $ で始まります。私の意見では、これらはメタデータを示すために使用されます。では、どの戦略が使用されているかのメタデータを示すために、これをデータ入力で使用してみてはいかがでしょうか?
{ "dados": { "$strategy": "sample", "copias": 15000 }, //... }
たとえば、持っているデータをサンプルとして 15,000 部注文できます。または、Athena でクエリを作成して、S3 に何かをリクエストします:
{ "dados": { "$strategy": "athena-query", "limit": 15000, "inicio": "2024-11-25", "fim": "2024-11-26", "cliente": "Abóbora" }, //... }
それともローカルパスにありますか?
{ "dados": { "$strategy": "localpath", "cwd": "/home/jeffque/random-project-file", "dir": "../payloads/esses-daqui/top10-hard/" }, //... }
それで、今後の戦略の選択を私に任せることができます。
コードレビューとファサード
戦略に対処するための私の最初のアプローチは次のとおりでした:
public DataLoader getDataLoader(Map<string object> inputDados) { final var strategy = (String) inputDados.get("$strategy"); return switch (strategy) { case "localpath" -> new LocalpathDataLoader(); case "sample" -> new SampleDataLoader(resourcePatternResolver_spring); case "athena-query" -> new AthenaQueryDataLoader(athenaClient, s3Client); default -> new AthenaQueryDataLoader(athenaClient, s3Client); } } </string>
そこで、私のアーキテクトはコードレビュー中に 2 つの質問をしました。
- 「なぜすべてをインスタンス化し、Spring を機能させないのですか?」
- 彼はコード内に DataLoaderFacade を作成しましたが、それを放棄しました 中途半端
このことから何が分かりましたか?ファサードを使用することは、処理を正しいコーナーに委任し、手動制御を放棄することをお勧めします?
そうですね、春のせいでたくさんの魔法が起こります。私たちは Java の専門知識を備えた Java ハウスにいるのですから、慣用的な Java/Spring を使用してみてはいかがでしょうか? 私個人として、いくつかの事柄を理解するのが難しいと感じるからといって、必ずしもそれが複雑であることを意味するわけではありません。それでは、Java 依存関係注入の魔法の世界を受け入れてみましょう。
ファサード オブジェクトの作成
以前は:
final var dataLoader = getDataLoader(inputDados) dataLoader.loadData(inputDados, workingPath);
次のようになりました:
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/schema", "$vocabulary": { //... } }
したがって、私の controller 層はこれを管理する必要はありません。ファサードまでお任せください
それでは、ファサードをどうするか?まず、すべてのオブジェクトをそれに注入する必要があります:
{ "dados": { "$strategy": "sample", "copias": 15000 }, //... }
メインの DataLoader については、@Service に加えて @Primary として記述します。残りは @Service で書き留めるだけです。
ここでこれをテストし、Spring がコンストラクターをどのように呼び出しているかを試すためだけに getDataLoader を null を返すように設定して、うまくいきました。ここで、各サービスがどのような戦略を使用しているかをメタデータでメモする必要があります...
これを行うには...
まあ、見てください! Java には アノテーション があります。そのコンポーネントで使用される戦略を含む ランタイム アノテーションを作成できます!
AthenaQueryDataLoader では次のようなものを作成できます。
{ "dados": { "$strategy": "athena-query", "limit": 15000, "inicio": "2024-11-25", "fim": "2024-11-26", "cliente": "Abóbora" }, //... }
エイリアスも持つことができます。そうしないのはなぜですか?
{ "dados": { "$strategy": "localpath", "cwd": "/home/jeffque/random-project-file", "dir": "../payloads/esses-daqui/top10-hard/" }, //... }
そして見せてください!
しかし、この注釈はどうやって作成するのでしょうか?そうですね、文字列のベクトルである属性を持たせる必要があります (Java コンパイラは、単独の文字列を提供し、それを位置 1 のベクトルに変換する処理をすでに処理しています)。デフォルト値は value です。次のようになります:
public DataLoader getDataLoader(Map<string object> inputDados) { final var strategy = (String) inputDados.get("$strategy"); return switch (strategy) { case "localpath" -> new LocalpathDataLoader(); case "sample" -> new SampleDataLoader(resourcePatternResolver_spring); case "athena-query" -> new AthenaQueryDataLoader(athenaClient, s3Client); default -> new AthenaQueryDataLoader(athenaClient, s3Client); } } </string>
注釈フィールドが値でない場合は、それを明示的にする必要があり、EstrategiaFeia 注釈のように見苦しくなります。
final var dataLoader = getDataLoader(inputDados) dataLoader.loadData(inputDados, workingPath);
私の意見では、それはあまり自然ではありません。
それでは、次のものがまだ必要です。
- 渡されたオブジェクトからクラスのアノテーションを抽出します
- 文字列マップを作成します → データローダー(または文字列) → と)
注釈の抽出とマップの組み立て
注釈を抽出するには、オブジェクト クラスにアクセスする必要があります。
dataLoaderFacade.loadData(inputDados, workingPath);
それに加えて、このクラスに Strategy:
のようなアノテーションが付けられているかどうかを尋ねてもいいですか?
@Service // para o Spring gerenciar esse componente como um serviço public class DataLoaderFacade implements DataLoader { public DataLoaderFacade(DataLoader primaryDataLoader, List<dataloader> dataLoaderWithStrategies) { // armazena de algum modo } @Override public CompletableFuture<void> loadData(Map<string object> input, Path workingPath) { return getDataLoader(input).loadData(input, workingPath); } private DataLoader getDataLoader(Map<string object> input) { final var strategy = input.get("$strategy"); // magia... } } </string></string></void></dataloader>
値フィールドがあることを覚えていますか?さて、このフィールドは文字列のベクトルを返します:
@Service @Primary @Estrategia("athena-query") public class AthenaQueryDataLoader implements DataLoader { // ... }
ショー!しかし、私には課題があります。以前は T 型のオブジェクトを持っていましたが、今はその同じオブジェクトを (T, String)[] にマップしたいと考えているからです。ストリームでは、これを行う古典的な操作は flatMap です。また、Java では、そのようなタプルを突然返すことはできませんが、それを使用してレコードを作成することはできます。
次のようになります:
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/schema", "$vocabulary": { //... } }
戦略の注釈が付けられていないオブジェクトがある場合はどうなりますか?それはNPEを与えるでしょうか?それはやめた方が良いので、NPE の前にフィルタリングして除外しましょう:
{ "dados": { "$strategy": "sample", "copias": 15000 }, //... }
そう考えると、まだ地図をまとめる必要があります。そして、見てください。Java はすでにこのためのコレクターを提供しています。 Collector.toMap(keyMapper, valueMapper)
{ "dados": { "$strategy": "athena-query", "limit": 15000, "inicio": "2024-11-25", "fim": "2024-11-26", "cliente": "Abóbora" }, //... }
ここまではOK。しかし、私は flatMap が特に気になりました。 MapMulti と呼ばれる新しい Java API があり、これには次のような可能性が秘められています。
{ "dados": { "$strategy": "localpath", "cwd": "/home/jeffque/random-project-file", "dir": "../payloads/esses-daqui/top10-hard/" }, //... }
美しさ。 DataLoader 用に取得しましたが、RuleLoader でも同じことを行う必要があります。それともそうではないでしょうか?お気づきかと思いますが、このコードには DataLoader に固有のものは何もありません。このコードを抽象化できます!!
public DataLoader getDataLoader(Map<string object> inputDados) { final var strategy = (String) inputDados.get("$strategy"); return switch (strategy) { case "localpath" -> new LocalpathDataLoader(); case "sample" -> new SampleDataLoader(resourcePatternResolver_spring); case "athena-query" -> new AthenaQueryDataLoader(athenaClient, s3Client); default -> new AthenaQueryDataLoader(athenaClient, s3Client); } } </string>
ファサードの下
純粋に実用的な理由から、私はこのアルゴリズムを注釈内に配置しました:
final var dataLoader = getDataLoader(inputDados) dataLoader.loadData(inputDados, workingPath);
そしてファサードについては?まあ、仕事も同じことを言うのが良いです。私はこれを抽象化することにしました:
dataLoaderFacade.loadData(inputDados, workingPath);
ファサードは次のようになります:
@Service // para o Spring gerenciar esse componente como um serviço public class DataLoaderFacade implements DataLoader { public DataLoaderFacade(DataLoader primaryDataLoader, List<dataloader> dataLoaderWithStrategies) { // armazena de algum modo } @Override public CompletableFuture<void> loadData(Map<string object> input, Path workingPath) { return getDataLoader(input).loadData(input, workingPath); } private DataLoader getDataLoader(Map<string object> input) { final var strategy = input.get("$strategy"); // magia... } } </string></string></void></dataloader>
以上がJava でアノテーションを使用して戦略を立てるの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

jvm'sperformanceiscompetitivewitherruntimes、sped、safety、andproductivityの提供

javaachievesplatformedentenceTheThejavavirtualMachine(JVM)、avainwithcodetorunonanyplatformwithajvm.1)codescompiledintobytecode、notmachine-specificcode.2)

thejvmisanabstractcomputingMachineCrucialForrunningJavaProgramsDuetoitsPlatForm-IndopentInterChitecture.Itincludes:1)ClassLoaderForloadingClasses、2)Runtimedataareaforforforatastorage、3)executionEngineWithinterter、Jitcompiler、およびGarbagecolfecolfecolfececolfecolfer

jvmhasacloserelationshiptheosasittrantesjavabytecodecodecodecodecodecodecodecodecodecodecodecodecodetructions、manageSmemory、およびhandlesgarbagecollection.thisrelationshipallowsjavatorunonvariousosenvirnments、Butalsedentsはspeedifediferentjvmbeviorhiorsandosendisfredediferentjvmbehbehioorysando

Javaの実装「Write and、Run Everywherewhere」はBytecodeにコンパイルされ、Java仮想マシン(JVM)で実行されます。 1)Javaコードを書き、それをByteCodeにコンパイルします。 2)JVMがインストールされたプラットフォームでByteCodeが実行されます。 3)Javaネイティブインターフェイス(JNI)を使用して、プラットフォーム固有の機能を処理します。 JVMの一貫性やプラットフォーム固有のライブラリの使用などの課題にもかかわらず、Woraは開発効率と展開の柔軟性を大幅に向上させます。

javaachievesplatformentenceTheTheTheJavavirtualMachine(JVM)、CodetorunondifferentoperatingSystemswithOutModification.thejvmcompilesjavacodeplatform-IndopentedbyTecodeを承認することを許可します

javaispowerfulfulduetoitsplatformindepentence、object-orientednature、richstandardlibrary、performancecapability、andstrongsecurityfeatures.1)platformendependenceallowseplicationStorunonaydevicesupportingjava.2)オブジェクト指向のプログラマン型

上位のJava関数には、次のものが含まれます。1)オブジェクト指向プログラミング、サポートポリ型、コードの柔軟性と保守性の向上。 2)例外処理メカニズム、トライキャッチ式ブロックによるコードの堅牢性の向上。 3)ゴミ収集、メモリ管理の簡素化。 4)ジェネリック、タイプの安全性の向上。 5)コードをより簡潔で表現力豊かにするためのAMBDAの表現と機能的なプログラミング。 6)最適化されたデータ構造とアルゴリズムを提供するリッチ標準ライブラリ。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

mPDF
mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

SublimeText3 中国語版
中国語版、とても使いやすい

WebStorm Mac版
便利なJavaScript開発ツール

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

Dreamweaver Mac版
ビジュアル Web 開発ツール
