ソフトウェア開発の世界では、デザイン パターンは一般的な問題に対する実績のある解決策として機能します。
あまり議論されていませんが、同様に重要なデザイン パターンのセットの 1 つが、GRASP (General Responsibility Assignment Software Patterns) です。 GRASP の原則は、多くの場合、SOLID 原則や他の OOP 設計パターンと相関しています。
GRASP (General Responsibility Assignment Software Patterns) は、オブジェクト指向設計においてクラスとオブジェクトに責任を割り当てることを目的としたガイドラインの集合です。 Javascript (Node.js) 開発でこれらのパターンをどのように使用できますか?もちろん、JavaScript はプロトタイプにネイティブに構築されたクラスをサポートしており、Java と同様の方法で GRASP を適用できます。
ただし、私の意見では、GRASP パターンは関数型プログラミングにも適用できます。
9 つの GRASP パターンは次のとおりです:
タスクを実行するために必要なデータまたは知識を持つ機能に責任を割り当てます。関数型プログラミングでは、タスクの実行に必要なデータまたはコンテキストを持つ関数またはモジュールに責任を割り当てることで、この原則を適用できます。
// User management module const createUser = (name, email) => ({ name, email }); const getUserEmail = (user) => user.email; const updateUserEmail = (user, newEmail) => ({ ...user, email: newEmail, }); const user = createUser('John Doe', 'john@example.com'); console.log(getUserEmail(user)); // 'john@example.com' const updatedUser = updateUserEmail(user, 'john.doe@example.com'); console.log(getUserEmail(updatedUser)); // 'john.doe@example.com'
ファクトリ関数を使用して、複雑なデータ構造またはオブジェクトを作成します。関数型プログラミングでは、オブジェクト指向プログラミングと同じ方法でクラスを扱いませんが、データ構造の作成またはオブジェクトの初期化の責任を、必要な情報と必要な情報を持つ関数またはモジュールに割り当てることによって、Creator 原則を適用できます。コンテキスト。
const createUser = (name, email) => ({ name, email });
高階関数を使用してシステム イベントを処理し、タスクを委任します。関数型プログラミングでは、コントローラーは多くの場合、システムの異なる部分間のデータとアクションの流れを調整する関数の形式をとり、責任が明確に分離されるようにします。
// Example of express.js controller const handleRequest = (req, res, userService) => { const user = userService.createUser(req.body.name, req.body.email); res.send(user); };
関数が独立しており、明示的な入力のみに依存していることを確認します。関数型プログラミングでは、他の関数やモジュールの内部詳細への依存を最小限に抑え、互いに独立して動作する関数やモジュールを設計することで低結合が実現されます
const sendEmail = (emailService, email) => emailService.send(email);
高い凝集性とは、モジュールまたは関数内の要素がどの程度一緒に属しているかを指します。関数型プログラミングにおいて、高い凝集性を達成するということは、明確に定義された単一のタスクまたは密接に関連した一連のタスクを実行するように関数とモジュールを設計することを意味します。
const createUser = (name, email) => ({ name, email }); const addUser = (users, user) => [...users, user]; const createAndAddUser = (users, name, email)=>{ const user = createUser(name, email); return addUser(users, user) } // usage const users = [ { name: 'Alice', email: 'alice@example.com' }, { name: 'Bob', email: 'bob@example.com' }, ]; const newUsers = createAndAddUser(users, 'Charlie', 'charlie@example.com');
高階関数と第一級関数を使用してポリモーフィズムを実現します。関数型プログラミングでは、ポリモーフィズムは通常、高階関数、ジェネリック関数、および Typescript
のような型システムを通じて実現されます。
const processPayment = (paymentMethod) => paymentMethod.process();
適切なドメイン関数またはクラスが存在しない場合に、ドメイン概念に直接対応しないが、必要な機能を提供するユーティリティ関数を作成します。
const log = (message) => console.log(message);
関数型プログラミングにおける間接化とは、システムの異なる部分間の相互作用を管理するための中間関数の使用を指します。 Node.js の良い例はミドルウェア パターンです。
const withNumberFilterMiddleware = (data) => data.filter(item => !isNaN(Number(item)));
関数型プログラミングにおける保護されたバリエーションとは、変化する部分をカプセル化し、システムの残りの部分がこれらのバリエーションから確実に保護されるようにすることで、変更に強い設計を作成することを意味します。 関数型プログラミングでは、抽象化、不変性、カプセル化を使用してこの原則を適用し、変更の影響を受けにくい堅牢で保守可能なコードを作成できます。
const processCreditCardPayment = (amount) => { console.log(`Processing credit card payment of ${amount}`); // Credit card payment logic }; const processPayPalPayment = (amount) => { console.log(`Processing PayPal payment of ${amount}`); // PayPal payment logic }; const processPayment = (paymentMethod, amount) => { paymentMethod(amount); }; // Use different payment methods without changing the processPayment function processPayment(processCreditCardPayment, 100); processPayment(processPayPalPayment, 200);
ご覧のとおり、GRASP 原則は、SOLID 原則だけでなく、多くの既知の設計パターンと相関しています。高い凝集性は、単一責任原則などとほぼ同じです。
これらの原則は OOP 原則であるだけでなく、関数型プログラミングであっても OOP プログラミングであっても、適切に設計されたクリーンなコードをプログラミングするための一般原則です。
以上がJavascript 関数型プログラミングの GRASPの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。