SOLID は、ロバート C. マーティン (アンクル ボブ) によって提案された、オブジェクト指向プログラミングの 5 つの基本原則を表す頭字語です。ここで彼の記事について詳しく読むことができます。
これらの原則は、コードの構造とメンテナンスを改善し、コードをより柔軟でスケーラブルにし、理解しやすくすることを目的としています。
これらの原則は、プログラマーがより組織化されたコードを作成し、責任を分担し、依存関係を減らし、リファクタリング プロセスを簡素化し、コードの再利用を促進するのに役立ちます。
頭字語の「S」は、「単一責任原則」 を表します。ボブおじさんがこの原則を定義するために使用したフレーズは次のとおりです:
「クラスには、変更する理由が 1 つだけ必要です。」
この原則に従って、クラスを開発するときは、その特定の機能を念頭に置く必要があります。クラスが 2 つの機能を扱う場合、最善の方法はそれを分割することです。
オブジェクト指向プログラミングを学習する場合、単一のクラスに複数の責任を割り当て、いわゆる神クラスを作成するのが一般的です。このアプローチは最初は効率的であるように見えますが、責任が複雑になるため、他に影響を与えずに一方を変更することが困難になります。
この問題の実際的な応用例を示すために、UserService というクラスを作成します。ユーザーに関するさまざまなニーズに対応します。
まず、単一責任原則を使用せずにこのクラスを適用する方法を見てみましょう。ここで、私たちのクラスはいくつかのことを行います: ユーザー データを操作し、このデータを検証し、データベースにユーザーを作成します。
import java.util.ArrayList; import java.util.List; class User { private int id; private String name; private String email; public User(int id, String name, String email) { this.id = id; this.name = name; this.email = email; } @Override public String toString() { return "User{id=" id ", name='" name "', email='" email "'}"; } } class UserService { private Listusers = new ArrayList(); public void addUser(String name, String email) { if (this.validateEmail(email)) { User newUser = new User(users.size() 1, name, email); users.add(newUser); saveToDatabase(newUser); } else { throw new IllegalArgumentException("E-mail inválido"); } } private boolean validateEmail(String email) { return email.matches("\\S @\\S \\.\\S "); } private void saveToDatabase(User user) { System.out.println("Salvando usuário no banco de dados " user); } public List getUsers() { return users; } public static void main(String[] args) { UserService userService = new UserService(); userService.addUser("John Doe", "[email protected]"); System.out.println(userService.getUsers()); } }
type User = { id: number, name: string, email: string } class UserService { private users: User[] = []; addUser(name: string, email: string) { if (this.validateEmail(email)) { const newUser = { id: this.users.length 1, name: name, email: email }; this.users.push(newUser); this.saveToDatabase(newUser); } else { throw new Error("E-mail inválido"); } } private validateEmail(email: string): boolean { const emailRegex = /\S @\S \.\S /; return emailRegex.test(email); } private saveToDatabase(user: User) { console.log("Salvando usuário no banco de dados", user); } getUsers() { return this.users; } }
ここで見られる主な問題はコードのメンテナンスです。検証ロジックやデータの保存方法に変更があった場合、このクラスに直接影響するため、保守が困難になります。
さて、どうすればこれを解決できるでしょうか?
神クラス「UserService」に含まれるロジックを、明確に定義された機能を持ついくつかのクラスに分離する必要があります。見てみましょう:
import java.util.ArrayList; import java.util.List; // validador class EmailValidator { public boolean validate(String email) { return email.matches("\\S @\\S \\.\\S "); } } // Repositório que manipula os dados no banco de dados class UserRepository { private Listusers = new ArrayList(); public void save(User user) { System.out.println("Salvando usuário no banco de dados " user); users.add(user); } public List getAll() { return users; } } // Aplicamos as regras do domain com injeção de dependências class UserService { private EmailValidator emailValidator; private UserRepository userRepository; public UserService(EmailValidator emailValidator, UserRepository userRepository) { this.emailValidator = emailValidator; this.userRepository = userRepository; } public void addUser(String name, String email) { if (emailValidator.validate(email)) { User newUser = new User(userRepository.getAll().size() 1, name, email); userRepository.save(newUser); } else { throw new IllegalArgumentException("E-mail inválido"); } } public List getUsers() { return userRepository.getAll(); } }
// validador class EmailValidator { validate(email: string): boolean { const emailRegex = /\S @\S \.\S /; return emailRegex.test(email); } } // Repositório que manipula os dados no banco de dados class UserRepository { private users: { id: number, name: string, email: string }[] = []; save(user: { id: number, name: string, email: string }) { console.log("Salvando usuário no banco de dados", user); this.users.push(user); } getAll() { return this.users; } } // Aplicamos as regras do domain com injeção de dependências class UserService { constructor( private emailValidator: EmailValidator, private userRepository: UserRepository ) {} addUser(name: string, email: string) { if (this.emailValidator.validate(email)) { const newUser = { id: this.userRepository.getAll().length 1, name: name, email: email }; this.userRepository.save(newUser); } else { throw new Error("E-mail inválido"); } } getUsers() { return this.userRepository.getAll(); } }
単一責任原則の適用は、堅牢でスケーラブルなソフトウェアを作成するために重要です。各クラスが 1 つの責任だけを持つようにすることで、コードの複雑さが軽減され、メンテナンスとリファクタリングが容易になり、エラーのリスクが最小限に抑えられます。この原則は、プロジェクトの品質と寿命を維持し、よりクリーンで効率的な設計を促進するための基本です。
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3