Dependency
23616 ワード
依存とは?
AがBに依存しているからといって、BもAに依存しているわけではない.
高度な依存性が悪い原因
高度な依存性により、モジュールの重複使用が減少します.独立せず、他の場所での使用が困難です.
依存規則
すべてのソースコード依存性は、外部から内部へ、低レベルから高レベルのポリシーへ移行する必要があります.
고수준 : 상위 수준의 개념, 추상화된 개념
ex. 업무로직: 데이터를 저장한다, 견적을 계산한다
저수준 : 추상화된 개념을 실제 어떻게 구현할지에 대한 세부적인 개념
ex. 세부사항: MySQL에 데이터를 저장한다, 선택 프로젝트의 견적을 계산한다
依存ルールの説明の追加説明
高度なモジュールは、低レベルのモジュールに依存することはできません.この2つのモジュールは、他の抽象に依存する必要があります.
抽象的なものは具体的なものに頼ってはいけない.具体的な抽象に頼らなければならない.
頻繁に変更されるインプリメンテーションクラスに依存しないでください.クラスの参照が必要な場合は、参照されるクラスが抽象クラスとして作成されます.関数を呼び出す必要がある場合は、呼び出された関数が抽象関数として作成されます.
通常、抽象クラスとインタフェースの変化は、自身から導かれる特定のクラスよりもずっと小さい.
What Data crosses the boundaries
:境界間でデータを渡す場合、何を渡す必要がありますか?
Crossing boundaries
:「制御フローは内部から外部に流れることができ、依存性ルールに違反するため、依存性逆転の原則を利用してこの問題を解決する必要があります.」
例えば、
1)抽象的なRepositoryインタフェースを使用すると,サービスはこれを参照する.
2)具体的なRDB Repositoryは、抽象的なRepositoryインタフェースを参照するために、これらのインタフェースを実装する
3)1),2)によってソースコードの依存性を逆転させることができ,サービスはデータベースの詳細を知らないため,データベースの変更も影響を受けない.
依存注入とは何ですか?
用語
依存性
//수정필요
B 클래스에서
A 클래스를 내부에 변수로 사용하게 됨으로써
B 클래스는 A 클래스에 의존관계가 생기게 됩니다.
ちゅうにゅう
内部ではなく外部からオブジェクトを作成して挿入
依存性注入
依存性注入は、パラメータに依存性を渡すと、モジュールへの依存性のロードや作成を回避するモードです.
DIのメリット
簡略化
依存コード
依存性注入方法
https://getchan.github.io/til/node_DI/
依存性注入前vs後
関連項目:https://velog.io/@moongq/Dependency-Injection
次のコードは依存注入前の従来のコードです.
//user-service.js
const User = require('./User_);
const UsersRepository = require('./users-repository);
async function getUsers() {
return UserRepository.findAll();
}
async function addUser(userData) {
const user = new User(userData);
return UserRepository.addUser(user):
}
module.exports = {
getUsers,
addUser
}
以上のコードのuser-service.jsは業務ロジックを担当し、ユーザーリポジトリはデータを担当する.しかし、2つの問題があります.サービスは、特定のリポジトリに関連付けられます.
他のリポジトリに変更した場合は、すべてのコードを変更する必要があります>拡張性が低いことを意味します.
モジュールのテストが難しくなりました.
外部ライブラリを使用してテストする必要があります>依存性の注入により、外部ライブラリの使用を最小限に抑えることができます.
const User = require('./User);
function UsersService(usersRepository) {
async function getUsers() {
return usersRepository.findAll();
}
async function addUser(userData) {
const user = new User(userData);
return usersRepository.addUser(user);
}
return {
getUsers,
addUser
};
}
module.exports = UsersService
注入依存性:Class vs function
関連項目:https://velog.io/@moongq/Dependency-Injection
1.クラス形式の依存性注入
:クラスのコンストラクション関数(constructor)に依存性を注入します.単一の依存性を単一のパラメータとして渡すよりも、オブジェクトを囲み、一度に渡すほうがいいです.
class UsersService {
constructor({ usersRepository, mailer, logger }) {
this.usersRepository = usersRepository;
this.mailer = mailer;
this.logger = logger;
}
async findAll() {
return this.usersRepository.findAll();
}
async addUser(user) {
await this.usersRepository.addUser(user);
this.logger.info(`User created ${user}`);
await this.mailer.sendConfirmationLink(user);
this.logger.info(`Confirmation link sent!: ${user}`);
}
}
module.exports = UsersService;
//ex. userController.js
require('./userService.js)
const usersService = new UsersService({
usersRepository,
mailer,
logger
});
2.関数形式の依存注入
export const userService = ({ usersRepository, mailer, logger }) => {
const fildAll = () => usersRepository.findAll();
addUser = (user) => {
await usersRepository. addUser(user);
logger.info(`User created: ${user}`);
await mailer.sendConfirmationLink(user);
logger.info(`Confirmation link sent ${user}`);
};
return {
findAll,
addUser
};
}
const service = usersService({
usersRepository,
mailer,
logger})
依存関係の設定
依存性注入の欠点は,利用すべきすべての依存性を予め設定し,構造化することである.
userServiceを生成する前に、依存性が集中している場所をcontainerと呼びます.次のコードに示します.
//container.js
const UsersRepository = require('./users-repository');
const Mailer = require('./mailer');
const Logger = require('./logger');
const UsersService = require('./users-service');
const InMemoryDataSource = require('./users-repository/data-source/in-memory');
const logger = new Logger({
level: process.env || 'dev'
});
const dataSource = new InMemoryDataSource();
const mailer = new Mailer({
templates: '/emails',
logger
});
const usersRepository = new UsersRepository({
logger,
dataSource
});
const usersService = new UsersService({
usersRepository,
mailer,
logger
});
module.exports = {
usersService
}
上記のコードに示すように、コンテナを1つずつ設定する必要がある場合、ライブラリAwilix
またはTypeDI
を使用して依存性を検索および取得することができる.リファレンス
用語参照
抽象クラス、定義実装クラス:https://zetawiki.com/wiki/%EC%B6%94%EC%83%81%ED%81%B4%EB%9E%98%EC%8A%A4,_%EA%B5%AC%EC%B2%B4%ED%81%B4%EB%9E%98%EC%8A%A4
:抽象クラス.インスタンス化できません
:ex.移動ツール
:具体的なカテゴリ.インスタンス化可能
トラック、自転車、船、飛行機...
https://itewbm.tistory.com/entry/%EC%B6%94%EC%83%81%ED%81%B4%EB%9E%98%EC%8A%A4abstract-class%EC%9D%98-%EC%A1%B4%EC%9E%AC-%EC%9D%B4%EC%9C%A0
依存性リファレンス
https://medium.com/@jang.wangsu/di-dependency-injection-%EC%9D%B4%EB%9E%80-1b12fdefec4f
https://getchan.github.io/til/node_DI/
https://velog.io/@moongq/Dependency-Injection
https://getchan.github.io/til/node_DI/
Reference
この問題について(Dependency), 我々は、より多くの情報をここで見つけました https://velog.io/@jch9537/Dependencyテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol