- VisualStudio2022
- pprof-Hướng dẫn sử dụng nó trong bản mạng trực tiếp
- Triển khai C# các loại hộp chọn nhiều màu lựa chọn thả xuống, cây lựa chọn nhiều màu lựa chọn thả xuống và các nút tối đa
- [Ghi chú học tập] Cơ sở dữ liệu cấu trúc: cat tree
Website chia sẻ công nghệ thuần túy nhất, tạo chuyên mục lập trình kỹ thuật chất lượng cao! Lập trình mạng nâng cao.
https://yccoding.com/ .
Mẫu thiết kế Địa chỉ dự án Git: https://github.com/yangchong211/YCDesignBlog.
Nguyên tắc Trách nhiệm duy nhất (SRP) là một nguyên tắc quan trọng của thiết kế hướng đối tượng, nhấn mạnh rằng một lớp hoặc mô-đun chỉ chịu trách nhiệm hoàn thành một trách nhiệm hoặc chức năng cụ thể. Bằng cách phân tách các hàm phức tạp thành nhiều lớp với độ chi tiết nhỏ và các hàm đơn lẻ, tính linh hoạt, khả năng bảo trì và khả năng mở rộng của hệ thống có thể được cải thiện.
Bài viết này giới thiệu chi tiết cách hiểu nguyên tắc trách nhiệm duy nhất, bao gồm ứng dụng của nó ở cấp độ phương pháp, giao diện và lớp, đồng thời giải thích các ưu điểm và tiêu chí phán đoán của nó thông qua các ví dụ cụ thể. Ngoài ra, nó cũng thảo luận về cách cân bằng thiết kế các lớp trong quá trình phát triển thực tế để tránh sự gia tăng độ phức tạp do sự phân chia quá mức gây ra.
Nguyên tắc trách nhiệm duy nhất (SRP) là một nguyên tắc quan trọng trong thiết kế hướng đối tượng.
Mô tả bằng tiếng Anh của nguyên tắc này như sau: Một lớp hoặc mô-đun nên có một trách nhiệm duy nhất.
Nếu chúng ta dịch sang tiếng Trung thì đó là: một lớp hoặc mô-đun chỉ chịu trách nhiệm hoàn thành một trách nhiệm (hoặc chức năng).
Bằng cách Việc phân chia các chức năng thành các mô-đun hoặc các lớp khác nhau, hệ thống có thể trở nên linh hoạt hơn, dễ bảo trì và mở rộng hơn.
Không khó để hiểu nghĩa đen. Trong một dự án, bạn sẽ thấy rằng “hiểu” và “sử dụng được” là hai công việc khác nhau, và “sử dụng tốt” lại càng khó khăn hơn.
Đánh giá từ kinh nghiệm làm việc, nhiều đồng nghiệp chưa hiểu Tường tận những nguyên tắc này, dẫn đến công việc áp dụng quy tắc quá giáo điều, coi nguyên tắc là đúng đắn và áp dụng một cách máy móc, phản tác.
Các đối tượng được mô tả bởi nguyên tắc đơn bao gồm hai, một lớp và một mô-đun.
Một cách hiểu là: hãy nghĩ về các mô-đun như một khái niệm vật tượng hơn các lớp và các lớp cũng có thể được coi là mô-đun. Một mô-đun chứa nhiều lớp và nhiều lớp tạo nên một mô-đun.
Để Bạn dễ hiểu, tiếp theo tôi sẽ chỉ giải quyết cách áp dụng nguyên tắc thiết kế này từ góc thiết kế “đẳng” cấp”. Đối với “mô-đun”, bạn có thể tự động mở rộng nó.
Định nghĩa và mô tả Nguyên tắc nhiệm vụ duy nhất rất đơn giản và không khó hiểu Một lớp chỉ cam chịu trách nhiệm hoàn thành một nhiệm vụ hoặc chức năng. chi tiết nhỏ và đơn chức năng. nói rằng trách nhiệm của nó không đủ đơn lẻ và nó phải được chia thành nhiều lớp với các hàm đơn và mức độ chi tiết lộ tốt hơn.
Ví dụ: một lớp chứa cả người vận hành và người vận hành. người dùng là hai mô hình kinh doanh độc lập. sẽ vi phạm nguyên tắc trách nhiệm duy nhất.
Để đáp ứng nguyên tắc trách nhiệm duy nhất, chúng ta cần chia lớp này thành hai lớp với mức độ chi tiết tốt hơn và các chức năng đơn lẻ: lớp đặt hàng và lớp người dùng.
Chúng ta tự tin vào công việc mình làm, vậy tại sao họ lại áp dụng nguyên tắc trách nhiệm duy nhất?
Chúng tôi có thể phát triển nhiều chức năng này.
Trước tiên chúng ta hãy xem cách phát triển khai báo đầu tiên:
public enumOperaEnum { UPDATE_USERNAME, UPDATE_PASSWORD; } giao diện công khai UserOperate { void updateUserInfo(OperateEnum type, UserInfo userInfo); } public class UserOperateImpl phát triển UserOperate{ @Override public void updateUserInfo(OperateEnum type, UserInfo userInfo) { if (type == OperationEnum.UPDATE_PASSWORD) { //Thay đổi mật khẩu} else if(type == OperatingEnum.UPDATE_USERNAME) { //Thay đổi tên người dùng} } }
Sau đó, hãy xem cách thực hiện thứ hai:
giao diện công khai UserOperate { void updateUserName(UserInfo userInfo); void updateUserPassword(UserInfo userInfo); } public class UserOperateImpl khai UserOperate { @Override public void updateUserName(UserInfo userInfo) { // Chỉnh sửa logic tên người dùng} @Override public void updateUserPassword(UserInfo userInfo ) { // Chỉnh sửa mật khẩu logic } }
Chúng ta hãy xem các sự khác biệt giữa hai cách phát triển này
Có thể thấy, thiết kế thứ hai phù hợp với nguyên tắc trách nhiệm duy nhất. nhiệm vụ duy nhất ở phương pháp cấp độ.
Li Si mua đồ hóa hóa Li Si phải nấu ăn sau khi đi chợ Về. Làm cách nào để thực hiện logic này?
Trước tiên chúng ta hãy xem cách phát triển khai báo đầu tiên:
/** * Làm việc nhà*/ giao diện công khai HouseWork { // Quét sàn void scannerFloor(); // Mua sắm void shopping(); } public class Zhangsan phát triển HouseWork{ @Override public void scanFloor() { // Quét sàn } @Override public void shopping() { } } public class Lisi phát triển khai HouseWork{ @Override public void scannerFloor() { } @Override public void shopping() { // Mua sắm} }
Đầu tiên, một giao diện để làm việc nhà được xác định và hai phương pháp được xác định là quét nhà và mua hàng tạp hóa Sau đó Lý Sĩ Cả Zhang San và Li Si đều viết lại phương this pháp luật, nhưng Li Si chỉ có cách thực hiện cụ thể.
Bản thân thiết kế này là không hợp lý. Trước hết: Trương Tam chỉ quét sàn, nhưng hắn cần viết lại phương pháp mua hàng tạp hóa, Lý Tư không cần quét sàn, nhưng Lý Tư cũng cần viết lại phương pháp quét sàn. Thứ hai: Điều này cũng không tuân theo nguyên tắc đóng mở. Để thêm một kiểu nấu ăn, cần phải sửa đổi ba lớp. Bằng cách này, khi logic rất phức tạp sẽ dễ gây ra những lỗi không mong muốn.
Thiết kế trên không tuân thủ nguyên tắc trách nhiệm duy nhất Sửa đổi một nơi sẽ ảnh hưởng đến những nơi khác không cần sửa đổi.
Sau đó, hãy xem cách thực hiện thứ hai:
/** * Làm việc nhà*/ giao diện công cộng Hoursework { } giao diện công cộng Mua sắm mở rộng Hoursework{ // Mua sắm void shopping(); } giao diện công cộng SweepFloor mở rộng Hoursework{ // Quét sàn void quétFlooring() } lớp công khai Zhangsan triển khai SweepFloor { @ Ghi đè public void scannerFlooring() { // Zhang San quét sàn} } public class Lisi thực hiện Mua sắm{ @Override public void shopping() { // Li Si Mua sắm} }
Việc nhà nói trên không được định nghĩa là một sự giao thoa mà việc quét nhà và việc nhà được tách riêng ra. Zhang San quét sàn, sau đó Zhang San thực hiện giao diện quét sàn. Khi Li Si mua sắm, Li Si thực hiện giao diện mua sắm. Sau này John Doe sẽ bổ sung thêm chức năng nấu ăn. Sau đó thêm giao diện nấu ăn mới. Lần này chỉ có Li Si cần thực hiện giao diện nấu ăn.
giao diện công khai Cooking mở rộng Hoursework{ void cook(); } lớp công khai Lisi thực hiện Mua sắm, Nấu ăn{ @Override public void shopping() { // Lisi shopping} @Override public void cook() { // Lisi cooks} }
Như trên, chúng ta thấy Zhang San không triển khai các giao diện dư thừa và Li Si cũng vậy. Và khi các chức năng mới được thêm vào, nó chỉ ảnh hưởng đến Li Si chứ không ảnh hưởng đến Zhang San.
Điều này phù hợp với nguyên tắc trách nhiệm duy nhất. Một lớp chỉ thực hiện một việc và việc sửa đổi nó sẽ không mang lại những thay đổi khác.
Từ cấp độ lớp, không có cách nào phân chia hoàn toàn theo nguyên tắc trách nhiệm duy nhất, nói cách khác, trách nhiệm của lớp có thể lớn hoặc nhỏ, không giống như giao diện, nó có thể được phân chia rõ ràng theo nguyên tắc trách nhiệm duy nhất. Miễn là nó hợp lý và hợp lý.
Ví dụ: chúng tôi có thể đăng ký, đăng nhập, đăng nhập bằng WeChat, đăng ký và đăng nhập cũng như các thao tác khác trên trang chủ của trang web.
giao diện công khai UserOperate { void login(UserInfo userInfo); void register(UserInfo userInfo); void logout(UserInfo userInfo); } public class UserOperateImpl triển khai UserOperate{ @Override public void login(UserInfo userInfo) { // Đăng nhập người dùng} @Override public void register(UserInfo userInfo) { // Đăng ký người dùng} @Ghi đè đăng xuất void void(UserInfo userInfo) { // Người dùng đăng xuất } }
Nếu phân chia theo nguyên tắc trách nhiệm duy nhất thì cũng có thể phân chia thành dạng sau.
giao diện công cộng Đăng ký { void register(); } giao diện công cộng Đăng nhập { void login(); } giao diện công cộng Đăng xuất { void logout(); } public class RegisterImpl thực hiện Đăng ký{ @Override public void register() { } } public class loginImpl thực hiện Đăng nhập{ @Override public void login() { // Đăng nhập người dùng} } public class LogoutImpl thực hiện Đăng xuất{ @Override public void logout() { } }
Trong phát triển phần mềm thực tế, rất khó để xác định liệu một lớp có một trách nhiệm duy nhất hay không. Hãy để tôi cho bạn một ví dụ thực tế hơn để giải thích.
Trong một sản phẩm xã hội, chúng tôi sử dụng lớp UserInfo sau để ghi lại thông tin người dùng. Bạn có nghĩ rằng thiết kế của lớp UserInfo đáp ứng nguyên tắc trách nhiệm duy nhất không?
public class UserInfo { userId chuỗi riêng tư; Chuỗi email riêng tư; Chuỗi riêng tư điện thoại; Chuỗi riêng tư cuối cùngLoginTime; Chuỗi riêng tư ProvinceOfAddress; // Khu vực riêng Chuỗi chi tiếtĐịa chỉ; // Địa chỉ chi tiết // . . . Các thuộc tính và phương thức khác bị bỏ qua. . . }
Có hai quan điểm khác nhau về vấn đề này.
Quan điểm nào đúng hơn? Trên thực tế, để lựa chọn trong số đó, chúng ta không thể tách rời khỏi các tình huống ứng dụng cụ thể.
Từ ví dụ vừa rồi, chúng ta có thể kết luận rằng trong các kịch bản ứng dụng khác nhau và các yêu cầu giai đoạn khác nhau, việc xác định liệu cùng một lớp có một trách nhiệm duy nhất có thể khác nhau hay không. Trong một kịch bản ứng dụng nhất định hoặc trong bối cảnh nhu cầu hiện tại, thiết kế của một lớp có thể đã đáp ứng nguyên tắc trách nhiệm duy nhất, nhưng nếu nó thay đổi sang một kịch bản ứng dụng khác hoặc trong bối cảnh của một nhu cầu nhất định trong tương lai thì nó có thể không phù hợp. hài lòng và cần tiếp tục được chia thành các lớp chi tiết hơn.
Đôi khi chúng ta không có một tiêu chuẩn rõ ràng và có thể định lượng được về việc trách nhiệm của một giai cấp có đủ đơn lẻ hay không. Có thể nói đây là một vấn đề rất chủ quan và những người nhân từ có quan điểm khác nhau.
Có thể bạn sẽ nói, nguyên tắc này mơ hồ và mơ hồ quá, chúng ta nên xử lý thế nào? Tôi cũng có một số mẹo ở đây có thể giúp bạn đánh giá liệu trách nhiệm của một lớp có đủ đơn lẻ hay không. Các nguyên tắc phán đoán sau đây mang tính hướng dẫn và thực thi nhiều hơn là suy nghĩ chủ quan về việc liệu một lớp có một trách nhiệm duy nhất hay không:
Làm thế nào để hiểu Nguyên tắc Trách nhiệm duy nhất (SRP)?
Một lớp chỉ chịu trách nhiệm hoàn thành một trách nhiệm hoặc chức năng. Đừng thiết kế các lớp lớn và toàn diện mà hãy thiết kế các lớp có độ chi tiết nhỏ và chức năng đơn lẻ. Nguyên tắc trách nhiệm duy nhất là đạt được sự gắn kết cao và độ ghép mã thấp, đồng thời cải thiện khả năng sử dụng lại, khả năng đọc và bảo trì mã.
Làm thế nào để đánh giá liệu trách nhiệm của một lớp có đủ đơn lẻ hay không?
Trách nhiệm của một lớp có nên được thiết kế đơn giản nhất có thể không?
Nguyên tắc trách nhiệm duy nhất cải thiện sự gắn kết của các lớp bằng cách tránh thiết kế các lớp lớn và toàn diện như ghép các chức năng không liên kết lại với nhau. phụ thuộc và phụ thuộc vào, làm giảm độ ghép của mã, từ đó đạt được mức độ gắn kết cao và ghép thấp of code.
Tuy nhiên, nếu việc phân chia quá chi tiết sẽ thực sự phản tác dụng, làm giảm khả năng gắn kết và ảnh hưởng khả năng bảo trì của mã hóa.
mô-đun | mô tả | Nhận xét |
---|---|---|
GitHub | Nhiều dự án nguồn mở dòng YC, bao gồm các thư viện thành phần Android và nhiều trường hợp | GitHub |
Blog tóm tắt | Tổng hợp Java, Android, C/C++, giao thức mạng, thuật toán, trình đơn tắt thiết lập, vv | YCblog |
thiết kế mẫu | Nguyên tắc thiết kế chính, 23 mẫu thiết kế, trường hợp thiết kế mẫu, đối tượng hướng dẫn duy nhất | thiết kế mẫu |
Cao nâng cấp Java | Thiết kế và nguyên tắc dữ liệu, ý tưởng cốt lõi của đối tượng hướng dẫn, IO, ngoại lệ, luồng và đồng thời, JVM | Cao nâng cấp Java |
network Protocol | Các trường hợp mạng thực tế, nguyên tắc và phân lớp mạng, HTTPS, yêu cầu mạng, xử lý sự cố | network Protocol |
máy tính nguyên tắc | Hướng dẫn cài đặt cấu hình, cơ chế xử lý ngoại lệ, nguyên tắc và hoạt động IO | khái niệm cơ bản về máy tính |
Học lập trình C | Hướng dẫn học tập có hệ thống và giao diện cho ngôn ngữ đầu vào cấp độ C, học cơ bản đến bốn trường hợp nhất vật thể | trình cài đặt C |
trình lập C++ | Hướng dẫn giảng dạy toàn diện và có hệ thống về sơ đồ ngôn ngữ C++, lập trình bài hát, các nguyên tắc cốt lõi | trình lập C++ |
Thuật toán thực hành | Canvas, mảng, danh sách liên kết, ngăn xếp, hàng chờ, cây, hàm băm, đệ quy, tìm kiếm, sắp xếp, vv | Leetcode |
Android | Giới thiệu cơ bản, mở nguồn mã thư viện giải nén, hiệu suất tối ưu, Framework, giải pháp thiết kế | Android |
23 thiết kế mẫu.
23 mẫu thiết kế & mô tả & cốt lõi chức năng | bao gồm |
---|---|
sáng tạo mô hình Cung cấp các trường hợp sử dụng để tạo đối tượng. use us in the software module |
Máy chủ mẫu Mô Hình Nhà Máy Trừu Tượng Mẫu đơn Build sample Mẫu nguyên mẫu |
Structure config Tập trung vào sự kết hợp của các lớp và đối tượng.Kết hợp các lớp hoặc đối tượng lại với nhau để tạo ra các cấu hình lớn hơn |
Bộ điều chỉnh mẫu Cầu mẫu Bộ lọc mẫu (Bộ lọc, Mẫu tiêu chí) Mẫu tổng hợp Mẫu trang trí Mẫu tiền Mẫu hạng ruồi Mẫu proxy |
model action vi Chú ý đặc biệt về giao tiếp giữa các đối tượng. đối tượng" |
Chuỗi nhiệm vụ Lệnh mẫu Sample user thông dịch Vòng lặp mẫu Bộ giải mã mẫu Mẫu lưu trữ vật phẩm Sample quan sát Trạng thái mẫu Empty object sample Lược đồ mẫu Mẫu mẫu Access client sample |
Cuối cùng, bài viết này về 02. Giải thích chi tiết về nguyên tắc trách nhiệm duy nhất kết thúc ở đây. về02. các bài viết liên quan hỗ trợ tôi trong blog tương lai .
Tôi mới bắt đầu phát triển ứng dụng iOS và cho đến nay đó là một trải nghiệm tuyệt vời. Tài liệu của Apple rất hay, nhưng tôi có một số câu hỏi không liên quan đến kỹ thuật và chỉ người có kinh nghiệm mới có thể trả lời. Tôi có một loạt UIViewControllers xử lý các điều khiển của chúng
Tôi đã bắt đầu học Reac-redux-immutable vài ngày trước, nhưng tôi vẫn còn bối rối về việc xây dựng ứng dụng của mình. Tôi có PHP (nền symfony/laravel MVC), vì vậy cần hiểu một số khái niệm về javascript
Mỗi lần tôi nhìn vào mã SharpDX và cố gắng làm theo tài liệu DirectX, tôi đều gặp khó khăn. Có nơi nào liệt kê rõ ràng mỗi lớp được đánh số sẽ ánh xạ tới điều gì và tại sao chúng tồn tại không? Tôi đang nói về một cái gì đó như thế này: D
Tôi đang tạo một ứng dụng bằng thư viện Robospice. Đây là một lựa chọn tuyệt vời để xử lý các kết nối Internet vì cốt lõi của thư viện dựa trên các dịch vụ Android nên các kết nối của chúng tôi độc lập với vòng đời Hoạt động. Chúng tôi đang tạo yêu cầu của mình và
Tôi có thể đang phân tích quá mức ở đây, nhưng dựa trên việc đọc MVC của tôi, dường như có rất nhiều ý kiến về cách thực hiện mọi việc. Có trang web hoặc tài liệu "các phương pháp hay nhất" xác định trách nhiệm của các phần khác nhau của MVC không? Hãy nhớ rằng, tôi đang sử dụng EF/Repository&U
Tôi là một lập trình viên xuất sắc, rất xuất sắc!