{"id":691,"date":"2025-04-12T16:11:48","date_gmt":"2025-04-12T08:11:48","guid":{"rendered":"https:\/\/www.hyy.net\/?p=691"},"modified":"2025-04-12T16:11:48","modified_gmt":"2025-04-12T08:11:48","slug":"net-7-design-patterns-in-depth-1-introduction-to-design-patterns","status":"publish","type":"post","link":"https:\/\/diji.net\/?p=691","title":{"rendered":"NET 7 Design Patterns In-Depth 1. Introduction to Design Patterns"},"content":{"rendered":"<p>Chapter 1 Introduction to Design Patterns<\/p>\n<h2>Introduction<\/h2>\n<h2>\u7b80\u4ecb<\/h2>\n<p>One of the problems in understanding and using design patterns is the need for proper insight into software architecture and the reason for using design patterns. When this insight does not exist, design patterns will increase complexity. As they are not used in their proper place, the use of design patterns will be considered a waste of work. The reason for this is that the design patterns will not be able to have a good impact on quality because they need to be placed in the right place.<\/p>\n<p>\u7406\u89e3\u548c\u4f7f\u7528\u8bbe\u8ba1\u6a21\u5f0f\u7684\u95ee\u9898\u4e4b\u4e00\u662f\u9700\u8981\u6b63\u786e\u4e86\u89e3\u8f6f\u4ef6\u4f53\u7cfb\u7ed3\u6784\u4ee5\u53ca\u4f7f\u7528\u8bbe\u8ba1\u6a21\u5f0f\u7684\u539f\u56e0\u3002\u5f53\u8fd9\u79cd\u6d1e\u5bdf\u529b\u4e0d\u5b58\u5728\u65f6\uff0c\u8bbe\u8ba1\u6a21\u5f0f\u5c06\u589e\u52a0\u590d\u6742\u6027\u3002\u7531\u4e8e\u5b83\u4eec\u6ca1\u6709\u5728\u9002\u5f53\u7684\u4f4d\u7f6e\u4f7f\u7528\uff0c\u56e0\u6b64\u4f7f\u7528\u8bbe\u8ba1\u6a21\u5f0f\u5c06\u88ab\u89c6\u4e3a\u6d6a\u8d39\u5de5\u4f5c\u3002\u8fd9\u6837\u505a\u7684\u539f\u56e0\u662f\uff0c\u8bbe\u8ba1\u6a21\u5f0f\u65e0\u6cd5\u5bf9\u8d28\u91cf\u4ea7\u751f\u597d\u7684\u5f71\u54cd\uff0c\u56e0\u4e3a\u5b83\u4eec\u9700\u8981\u653e\u5728\u6b63\u786e\u7684\u4f4d\u7f6e\u3002<\/p>\n<p>In this chapter, an attempt has been made to briefly examine the software architecture and design patterns. The enterprise applications architecture has been introduced, and the relationship between software design problems and design patterns has been clarified. In the rest of the chapter, a brief look at .NET, some object-oriented principles, and the UML is given because, throughout the book, UML is used for modeling, and the .NET framework and C# language are used for sample codes.<br \/>\n\u5728\u672c\u7ae0\u4e2d\uff0c\u6211\u4eec\u5c1d\u8bd5\u7b80\u8981\u5730\u7814\u7a76\u4e86\u8f6f\u4ef6\u4f53\u7cfb\u7ed3\u6784\u548c\u8bbe\u8ba1\u6a21\u5f0f\u3002\u4ecb\u7ecd\u4e86\u4f01\u4e1a\u5e94\u7528\u7a0b\u5e8f\u4f53\u7cfb\u7ed3\u6784\uff0c\u5e76\u9610\u660e\u4e86\u8f6f\u4ef6\u8bbe\u8ba1\u95ee\u9898\u548c\u8bbe\u8ba1\u6a21\u5f0f\u4e4b\u95f4\u7684\u5173\u7cfb\u3002\u5728\u672c\u7ae0\u7684\u5176\u4f59\u90e8\u5206\uff0c\u7b80\u8981\u4ecb\u7ecd\u4e86 .NET\u3001\u4e00\u4e9b\u9762\u5411\u5bf9\u8c61\u7684\u539f\u5219\u4ee5\u53ca UML\uff0c\u56e0\u4e3a\u5728\u6574\u672c\u4e66\u4e2d\uff0cUML \u7528\u4e8e\u5efa\u6a21\uff0c\u800c .NET \u6846\u67b6\u548c C# \u8bed\u8a00\u7528\u4e8e\u793a\u4f8b\u4ee3\u7801\u3002<\/p>\n<h2>Structure<\/h2>\n<h2>\u7ed3\u6784<\/h2>\n<p>In this chapter, we will cover the following topics:<br \/>\n\u5728\u672c\u7ae0\u4e2d\uff0c\u6211\u4eec\u5c06\u4ecb\u7ecd\u4ee5\u4e0b\u4e3b\u9898\uff1a<\/p>\n<ul>\n<li>What is software architecture<\/li>\n<li>What are design patterns<\/li>\n<li>GoF design patterns<\/li>\n<li>Enterprise application and its design patterns<\/li>\n<li>\n<ul>\n<li>Different types of enterprise applications<\/li>\n<\/ul>\n<\/li>\n<li>Design patterns and software design problems<\/li>\n<li>\n<ul>\n<li>Effective factors in choosing a design pattern<\/li>\n<\/ul>\n<\/li>\n<li>.NET<\/li>\n<li>\n<ul>\n<li>Introduction to object orientation in .NET<\/li>\n<\/ul>\n<\/li>\n<li>Object orientation SOLID principles<\/li>\n<li>UML class diagram<\/li>\n<li>Conclusion<\/li>\n<\/ul>\n<h2>Objectives<\/h2>\n<h2>\u76ee\u6807<\/h2>\n<p>By the end of this chapter, you will be able to understand the role and place of design patterns in software design, be familiar with software architecture, and evaluate software design problems from different aspects. You are also expected to have a good view of SOLID design principles at the end of this chapter and get to know .NET and UML.<\/p>\n<p>\u901a\u8fc7\u672c\u7ae0\u7684\u7ed3\u5c3e\uff0c\u60a8\u5c06\u80fd\u591f\u7406\u89e3\u8bbe\u8ba1\u6a21\u5f0f\u5728\u8f6f\u4ef6\u8bbe\u8ba1\u4e2d\u7684\u4f5c\u7528\u548c\u5730\u4f4d\uff0c\u719f\u6089\u8f6f\u4ef6\u67b6\u6784\uff0c\u5e76\u4ece\u4e0d\u540c\u65b9\u9762\u8bc4\u4f30\u8f6f\u4ef6\u8bbe\u8ba1\u95ee\u9898\u3002\u5728\u672c\u7ae0\u7684\u672b\u5c3e\uff0c\u60a8\u8fd8\u5e94\u8be5\u5bf9 SOLID \u8bbe\u8ba1\u539f\u5219\u6709\u4e00\u4e2a\u5f88\u597d\u7684\u4e86\u89e3\uff0c\u5e76\u4e86\u89e3 .NET \u548c UML\u3002<\/p>\n<h2>What is software architecture<\/h2>\n<h2>\u4ec0\u4e48\u662f\u8f6f\u4ef6\u67b6\u6784<\/h2>\n<p>Today, there are various definitions for software architecture. The system\u2019s basic structure, related to design decisions, must be made in the initial steps of software production. The common feature in all these definitions is their importance. Regardless of our attitude towards software architecture, we must always consider that suitable architecture can be developed and maintained. Also, when we want to look at the software from an architectural point of view, we must know what elements and items are of great importance and always try to keep those important elements and items in the best condition.<\/p>\n<p>\u4eca\u5929\uff0c\u8f6f\u4ef6\u67b6\u6784\u6709\u591a\u79cd\u5b9a\u4e49\u3002\u7cfb\u7edf\u7684\u57fa\u672c\u7ed3\u6784\u4e0e\u8bbe\u8ba1\u51b3\u7b56\u76f8\u5173\uff0c\u5fc5\u987b\u5728\u8f6f\u4ef6\u751f\u4ea7\u7684\u521d\u59cb\u6b65\u9aa4\u4e2d\u5236\u5b9a\u3002\u6240\u6709\u8fd9\u4e9b\u5b9a\u4e49\u7684\u5171\u540c\u7279\u5f81\u662f\u5b83\u4eec\u7684\u91cd\u8981\u6027\u3002\u65e0\u8bba\u6211\u4eec\u5bf9\u8f6f\u4ef6\u67b6\u6784\u7684\u6001\u5ea6\u5982\u4f55\uff0c\u6211\u4eec\u90fd\u5fc5\u987b\u59cb\u7ec8\u8003\u8651\u53ef\u4ee5\u5f00\u53d1\u548c\u7ef4\u62a4\u5408\u9002\u7684\u67b6\u6784\u3002\u6b64\u5916\uff0c\u5f53\u6211\u4eec\u60f3\u4ece\u67b6\u6784\u7684\u89d2\u5ea6\u6765\u770b\u8f6f\u4ef6\u65f6\uff0c\u6211\u4eec\u5fc5\u987b\u77e5\u9053\u54ea\u4e9b\u5143\u7d20\u548c\u9879\u76ee\u975e\u5e38\u91cd\u8981\uff0c\u5e76\u59cb\u7ec8\u5c1d\u8bd5\u4f7f\u8fd9\u4e9b\u91cd\u8981\u7684\u5143\u7d20\u548c\u9879\u76ee\u5904\u4e8e\u6700\u4f73\u72b6\u6001\u3002<\/p>\n<p>Consider software that needs to be better designed, and its essential elements must be identified. During the production and maintenance of this software, we will need help with various problems, including implementing changes, which will reduce the speed of providing new features and increase the volume of software errors and bugs. For example, pay attention to the following figure:<\/p>\n<p>\u8003\u8651\u9700\u8981\u66f4\u597d\u8bbe\u8ba1\u7684\u8f6f\u4ef6\uff0c\u5e76\u4e14\u5fc5\u987b\u786e\u5b9a\u5176\u57fa\u672c\u5143\u7d20\u3002\u5728\u8be5\u8f6f\u4ef6\u7684\u5236\u4f5c\u548c\u7ef4\u62a4\u8fc7\u7a0b\u4e2d\uff0c\u6211\u4eec\u5c06\u9700\u8981\u5e2e\u52a9\u89e3\u51b3\u5404\u79cd\u95ee\u9898\uff0c\u5305\u62ec\u5b9e\u65bd\u66f4\u6539\uff0c\u8fd9\u5c06\u964d\u4f4e\u63d0\u4f9b\u65b0\u529f\u80fd\u7684\u901f\u5ea6\u5e76\u589e\u52a0\u8f6f\u4ef6\u9519\u8bef\u548c\u9519\u8bef\u7684\u6570\u91cf\u3002\u4f8b\u5982\uff0c\u8bf7\u6ce8\u610f\u4e0b\u56fe\uff1a<\/p>\n<p><img decoding=\"async\" src=\"\/net7designpatternsindepth\/0101.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 1.1: An example of software without proper architecture<br \/>\n\u56fe 1.1\uff1a \u6ca1\u6709\u9002\u5f53\u67b6\u6784\u7684\u8f6f\u4ef6\u793a\u4f8b<\/p>\n<p>In the preceding figure, full cells are the new features provided, and empty cells are the design and architectural problems and defects.<\/p>\n<p>\u5728\u4e0a\u56fe\u4e2d\uff0cfull cells \u662f\u63d0\u4f9b\u7684\u65b0\u529f\u80fd\uff0c\u800c empty cells \u662f\u8bbe\u8ba1\u548c\u4f53\u7cfb\u7ed3\u6784\u95ee\u9898\u548c\u7f3a\u9677\u3002<\/p>\n<p>If we consider one row of Figure 1.1, the following figure will be seen:<br \/>\n\u5982\u679c\u6211\u4eec\u8003\u8651\u56fe 1.1 \u7684\u4e00\u884c\uff0c\u5c06\u770b\u5230\u4e0b\u56fe\uff1a<\/p>\n<p><img decoding=\"async\" src=\"\/net7designpatternsindepth\/0102.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 1.2: Sample feature delivery in software without proper architecture<br \/>\n\u56fe 1.2\uff1a \u6ca1\u6709\u9002\u5f53\u67b6\u6784\u7684\u8f6f\u4ef6\u4e2d\u7684\u529f\u80fd\u4ea4\u4ed8\u793a\u4f8b<\/p>\n<p>We see how much time it takes to provide three different features. If the correct design and architecture were adopted, new features would be delivered more quickly. The same row could be presented as the following figure:<\/p>\n<p>\u6211\u4eec\u4e86\u89e3\u63d0\u4f9b\u4e09\u79cd\u4e0d\u540c\u529f\u80fd\u9700\u8981\u591a\u5c11\u65f6\u95f4\u3002\u5982\u679c\u91c7\u7528\u6b63\u786e\u7684\u8bbe\u8ba1\u548c\u67b6\u6784\uff0c\u65b0\u529f\u80fd\u5c06\u66f4\u5feb\u5730\u4ea4\u4ed8\u3002\u540c\u4e00\u884c\u53ef\u4ee5\u663e\u793a\u4e3a\u4e0b\u56fe\uff1a<\/p>\n<p><img decoding=\"async\" src=\"\/net7designpatternsindepth\/0103.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 1.3: Sample feature delivery in software WITH proper architecture<br \/>\n\u56fe 1.3\uff1a \u5177\u6709\u9002\u5f53\u67b6\u6784\u7684\u8f6f\u4ef6\u4e2d\u7684\u793a\u4f8b\u529f\u80fd\u4ea4\u4ed8<\/p>\n<p>The difference in length in the preceding two forms (Figure 1.2 and Figure 1.3) is significant. This shows the importance of the right design and architecture in the software. A high-quality infrastructure in the short term may indicate that production speed decreases. This natural and high-quality infrastructure will show its effect in the long run.<\/p>\n<p>\u524d\u4e24\u79cd\u5f62\u5f0f\uff08\u56fe 1.2 \u548c\u56fe 1.3\uff09\u7684\u957f\u5ea6\u5dee\u5f02\u5f88\u5927\u3002\u8fd9\u8868\u660e\u4e86\u8f6f\u4ef6\u4e2d\u6b63\u786e\u8bbe\u8ba1\u548c\u67b6\u6784\u7684\u91cd\u8981\u6027\u3002\u77ed\u671f\u5185\u9ad8\u8d28\u91cf\u7684\u57fa\u7840\u8bbe\u65bd\u53ef\u80fd\u8868\u660e\u751f\u4ea7\u901f\u5ea6\u4f1a\u964d\u4f4e\u3002\u4ece\u957f\u8fdc\u6765\u770b\uff0c\u8fd9\u79cd\u5929\u7136\u548c\u9ad8\u8d28\u91cf\u7684\u57fa\u7840\u8bbe\u65bd\u5c06\u663e\u793a\u51fa\u5176\u6548\u679c\u3002<\/p>\n<p>The following figure shows the relationship between Time and Output:<br \/>\n\u4e0b\u56fe\u5c55\u793a\u4e86 Time \u548c Output \u4e4b\u95f4\u7684\u5173\u7cfb\uff1a<\/p>\n<p><img decoding=\"async\" src=\"\/net7designpatternsindepth\/0104.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 1.4: Time-Output Relation in Software Delivery<br \/>\n\u56fe 1.4\uff1a \u8f6f\u4ef6\u4ea4\u4ed8\u4e2d\u7684\u65f6\u95f4-\u8f93\u51fa\u5173\u7cfb<\/p>\n<p>In Figure 1.4, at the beginning of the work, reaching the output with a low-quality Infrastructure is faster than with a high-quality Infrastructure. However, with the passage of time and the increase in the capabilities and complexity of the software, the ability to maintain and apply software change is accelerated with better quality infrastructure. This will reduce costs, increase user satisfaction, and improve maintenance.<\/p>\n<p>\u5728\u56fe 1.4 \u4e2d\uff0c\u5728\u5de5\u4f5c\u5f00\u59cb\u65f6\uff0c\u4f7f\u7528\u4f4e\u8d28\u91cf\u7684 Infrastructure \u6bd4\u4f7f\u7528\u9ad8\u8d28\u91cf\u7684 Infrastructure \u66f4\u5feb\u5730\u8fbe\u5230\u8f93\u51fa\u3002\u4f46\u662f\uff0c\u968f\u7740\u65f6\u95f4\u7684\u63a8\u79fb\u4ee5\u53ca\u8f6f\u4ef6\u529f\u80fd\u548c\u590d\u6742\u6027\u7684\u589e\u52a0\uff0c\u7ef4\u62a4\u548c\u5e94\u7528\u8f6f\u4ef6\u66f4\u6539\u7684\u80fd\u529b\u4f1a\u968f\u7740\u66f4\u9ad8\u8d28\u91cf\u7684\u57fa\u7840\u8bbe\u65bd\u800c\u52a0\u901f\u3002\u8fd9\u5c06\u964d\u4f4e\u6210\u672c\u3001\u63d0\u9ad8\u7528\u6237\u6ee1\u610f\u5ea6\u5e76\u6539\u5584\u7ef4\u62a4\u3002<\/p>\n<p>In this regard, Gerald Weinberg, the late American computer science scientist, has a quote that says,<\/p>\n<p>\u5728\u8fd9\u65b9\u9762\uff0c\u5df2\u6545\u7684\u7f8e\u56fd\u8ba1\u7b97\u673a\u79d1\u5b66\u79d1\u5b66\u5bb6\u6770\u62c9\u5c14\u5fb7\u00b7\u6e29\u4f2f\u683c \uff08Gerald Weinberg\uff09 \u6709\u4e00\u53e5\u8bdd\u8bf4\uff1a<\/p>\n<p>\u201cIf builders-built buildings the way programmers wrote programs, then the first woodpecker that came along would destroy civilization.\u201d<\/p>\n<p>\u201c\u5982\u679c\u5efa\u7b51\u5546\u6309\u7167\u7a0b\u5e8f\u5458\u7f16\u5199\u7a0b\u5e8f\u7684\u65b9\u5f0f\u5efa\u9020\u5efa\u7b51\u7269\uff0c\u90a3\u4e48\u51fa\u73b0\u7684\u7b2c\u4e00\u53ea\u5544\u6728\u9e1f\u5c31\u4f1a\u6467\u6bc1\u6587\u660e\u3002\u201d<\/p>\n<p>Weinberg tried to express the importance of infrastructure and software architecture. According to Weinberg\u2019s quote, paying attention to maintainability in the design and implementation of software solutions is important. Today, various principles can be useful in reaching a suitable infrastructure.<\/p>\n<p>Weinberg \u8bd5\u56fe\u8868\u8fbe\u57fa\u7840\u8bbe\u65bd\u548c\u8f6f\u4ef6\u67b6\u6784\u7684\u91cd\u8981\u6027\u3002\u6839\u636e Weinberg \u7684\u5f15\u8ff0\uff0c\u5728\u8f6f\u4ef6\u89e3\u51b3\u65b9\u6848\u7684\u8bbe\u8ba1\u548c\u5b9e\u65bd\u4e2d\u6ce8\u610f\u53ef\u7ef4\u62a4\u6027\u5f88\u91cd\u8981\u3002\u4eca\u5929\uff0c\u5404\u79cd\u539f\u5219\u90fd\u6709\u52a9\u4e8e\u5b9e\u73b0\u5408\u9002\u7684\u57fa\u7840\u8bbe\u65bd\u3002<\/p>\n<p>Some of these principles are as follows:<br \/>\n\u5176\u4e2d\u4e00\u4e9b\u539f\u5219\u5982\u4e0b\uff1a<\/p>\n<ul>\n<li>\n<p>Separation of concerns: Different software parts should be separated from each other according to their work.<br \/>\n\u5173\u6ce8\u70b9\u5206\u79bb\uff1a\u4e0d\u540c\u7684\u8f6f\u4ef6\u90e8\u5206\u5e94\u6839\u636e\u5176\u5de5\u4f5c\u60c5\u51b5\u76f8\u4e92\u5206\u79bb\u3002<\/p>\n<\/li>\n<li>\n<p>Encapsulation: This is a way to restrict the direct access to some components of an object, so users cannot access state values for all the variables of a particular object. Encapsulation can hide data members, functions, or methods associated with an instantiated class or object. Users will have no idea how classes are implemented or stored, and the users will only know that the values are being passed and initialized (Data Hiding). Also, it would be easy to change and adapt to new requirements (ease of use) using Encapsulation.<br \/>\n\u5c01\u88c5\uff1a\u8fd9\u662f\u4e00\u79cd\u9650\u5236\u5bf9\u5bf9\u8c61\u67d0\u4e9b\u7ec4\u4ef6\u7684\u76f4\u63a5\u8bbf\u95ee\u7684\u65b9\u6cd5\uff0c\u56e0\u6b64\u7528\u6237\u65e0\u6cd5\u8bbf\u95ee\u7279\u5b9a\u5bf9\u8c61\u7684\u6240\u6709\u53d8\u91cf\u7684\u72b6\u6001\u503c\u3002\u5c01\u88c5\u53ef\u4ee5\u9690\u85cf\u4e0e\u5b9e\u4f8b\u5316\u7684\u7c7b\u6216\u5bf9\u8c61\u5173\u8054\u7684\u6570\u636e\u6210\u5458\u3001\u51fd\u6570\u6216\u65b9\u6cd5\u3002\u7528\u6237\u5c06\u4e0d\u77e5\u9053\u7c7b\u662f\u5982\u4f55\u5b9e\u73b0\u6216\u5b58\u50a8\u7684\uff0c\u7528\u6237\u53ea\u77e5\u9053\u503c\u6b63\u5728\u4f20\u9012\u548c\u521d\u59cb\u5316\uff08\u6570\u636e\u9690\u85cf\uff09\u3002\u6b64\u5916\uff0c\u4f7f\u7528 Capsulation \u5f88\u5bb9\u6613\u66f4\u6539\u548c\u9002\u5e94\u65b0\u7684\u9700\u6c42\uff08\u6613\u7528\u6027\uff09\u3002<\/p>\n<\/li>\n<li>\n<p>Dependency inversion: High-level modules should not depend on low-level modules, and the dependence between these two should only happen through abstractions. To clarify the issue, consider the following example:<br \/>\nWe have two different times in software production: compile and run time. Suppose that in a dependency graph at compile-time, the following relationship exists between classes A, B, and C:<br \/>\n\u4f9d\u8d56\u53cd\u8f6c\uff1a\u9ad8\u7ea7\u6a21\u5757\u4e0d\u5e94\u8be5\u4f9d\u8d56\u4f4e\u7ea7\u6a21\u5757\uff0c\u8fd9\u4e24\u8005\u4e4b\u95f4\u7684\u4f9d\u8d56\u5173\u7cfb\u53ea\u80fd\u901a\u8fc7\u62bd\u8c61\u6765\u5b9e\u73b0\u3002\u4e3a\u4e86\u6f84\u6e05\u8fd9\u4e2a\u95ee\u9898\uff0c\u8bf7\u8003\u8651\u4ee5\u4e0b\u793a\u4f8b\uff1a<br \/>\n\u6211\u4eec\u5728\u8f6f\u4ef6\u751f\u4ea7\u4e2d\u6709\u4e24\u4e2a\u4e0d\u540c\u7684\u65f6\u95f4\uff1a\u7f16\u8bd1\u548c\u8fd0\u884c\u65f6\u3002\u5047\u8bbe\u5728\u7f16\u8bd1\u65f6\u7684\u4f9d\u8d56\u5173\u7cfb\u56fe\u4e2d\uff0c\u7c7b A\u3001B \u548c C \u4e4b\u95f4\u5b58\u5728\u4ee5\u4e0b\u5173\u7cfb\uff1a<\/p>\n<\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"\/net7designpatternsindepth\/0105.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 1.5: Relationship between A, B, and C in compile-time<br \/>\n\u56fe 1.5\uff1a \u7f16\u8bd1\u65f6 A\u3001B \u548c C \u4e4b\u95f4\u7684\u5173\u7cfb<\/p>\n<p>As you can see, at compile-time, A is directly connected to B to call a method in B, and the exact relationship is true for the relationship between B and C. This connection will be established in the same way during runtime as follows:<\/p>\n<p>\u5982\u4f60\u6240\u89c1\uff0c\u5728\u7f16\u8bd1\u65f6\uff0cA \u76f4\u63a5\u8fde\u63a5\u5230 B \u4ee5\u8c03\u7528 B \u4e2d\u7684\u65b9\u6cd5\uff0c\u5e76\u4e14 B \u548c C \u4e4b\u95f4\u7684\u5173\u7cfb\u6b63\u662f\u5982\u6b64\u3002\u6b64\u8fde\u63a5\u5c06\u5728\u8fd0\u884c\u65f6\u4ee5\u76f8\u540c\u7684\u65b9\u5f0f\u5efa\u7acb\uff0c\u5982\u4e0b\u6240\u793a\uff1a<\/p>\n<p><img decoding=\"async\" src=\"\/net7designpatternsindepth\/0106.png\" alt=\"alt text\" \/><br \/>\nFigure 1.6: Relationship between A, B, and C in runtime<br \/>\n\u56fe 1.6.. \u8fd0\u884c\u65f6 A\u3001B \u548c C \u4e4b\u95f4\u7684\u5173\u7cfb<\/p>\n<p>The problem in this type of communication is that there is no loose coupling between A-B and B-C, and these parts are highly dependent on each other and cause problems in maintainability. To solve this problem, instead of the direct connection between A and B, we consider the connection at compile-time based on abstractions as shown in the following figure:<\/p>\n<p>\u8fd9\u79cd\u7c7b\u578b\u7684\u901a\u4fe1\u7684\u95ee\u9898\u5728\u4e8e A-B \u548c B-C \u4e4b\u95f4\u6ca1\u6709\u677e\u6563\u7684\u8026\u5408\uff0c\u5e76\u4e14\u8fd9\u4e9b\u90e8\u5206\u5f7c\u6b64\u9ad8\u5ea6\u4f9d\u8d56\uff0c\u5e76\u5bfc\u81f4\u53ef\u7ef4\u62a4\u6027\u95ee\u9898\u3002\u4e3a\u4e86\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u6211\u4eec\u5728\u7f16\u8bd1\u65f6\u6839\u636e\u62bd\u8c61\u6765\u8003\u8651\u8fde\u63a5\uff0c\u800c\u4e0d\u662f A \u548c B \u4e4b\u95f4\u7684\u76f4\u63a5\u8fde\u63a5\uff0c\u5982\u4e0b\u56fe\u6240\u793a\uff1a<\/p>\n<p><img decoding=\"async\" src=\"\/net7designpatternsindepth\/0107.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 1.7: Relationship between A, B, and C based on abstractions<br \/>\n\u56fe 1.7\uff1a \u57fa\u4e8e\u62bd\u8c61\u7684 A\u3001B \u548c C \u4e4b\u95f4\u7684\u5173\u7cfb<\/p>\n<p>In the prior connection, A depends on an abstraction from B at the compile-time, and B has implemented the corresponding abstraction. This change in communication type will ultimately remain the same as at runtime. But it will cause a loose coupling in the sense that the implementation of B can be changed without changing A.<\/p>\n<p>\u5728\u524d\u9762\u7684\u8fde\u63a5\u4e2d\uff0cA \u4f9d\u8d56\u4e8e\u7f16\u8bd1\u65f6\u6765\u81ea B \u7684\u62bd\u8c61\uff0c\u5e76\u4e14 B \u5df2\u7ecf\u5b9e\u73b0\u4e86\u76f8\u5e94\u7684\u62bd\u8c61\u3002\u901a\u4fe1\u7c7b\u578b\u7684\u8fd9\u79cd\u66f4\u6539\u6700\u7ec8\u5c06\u4e0e\u8fd0\u884c\u65f6\u76f8\u540c\u3002\u4f46\u5b83\u4f1a\u5bfc\u81f4\u677e\u6563\u8026\u5408\uff0c\u56e0\u4e3a B \u7684\u5b9e\u73b0\u53ef\u4ee5\u5728\u4e0d\u6539\u53d8 A \u7684\u60c5\u51b5\u4e0b\u6539\u53d8\u3002<\/p>\n<p>The communication during runtime in the prior mode is shown in the following figure:<\/p>\n<p>previous \u6a21\u5f0f\u4e0b\u8fd0\u884c\u65f6\u7684\u901a\u4fe1\u5982\u4e0b\u56fe\u6240\u793a\uff1a<\/p>\n<p><img decoding=\"async\" src=\"\/net7designpatternsindepth\/0108.png\" alt=\"alt text\" \/><br \/>\nFigure 1.8: Relationship between A, B, and C based on abstractions in runtime<br \/>\n\u56fe 1.8\uff1a \u8fd0\u884c\u65f6\u4e2d\u57fa\u4e8e\u62bd\u8c61\u7684 A\u3001B \u548c C \u4e4b\u95f4\u7684\u5173\u7cfb<\/p>\n<ul>\n<li>\n<p>Explicit dependencies: Classes and methods must be honest with their users. For example, attribute X must have a correct value for a class to function properly. This condition can be applied through the class constructor, and objects that cannot be used can be prevented from being created.<br \/>\n\u663e\u5f0f\u4f9d\u8d56\u9879\uff1a\u7c7b\u548c\u65b9\u6cd5\u5fc5\u987b\u5bf9\u5176\u7528\u6237\u8bda\u5b9e\u3002\u4f8b\u5982\uff0c\u5c5e\u6027 X \u5fc5\u987b\u5177\u6709\u6b63\u786e\u7684\u503c\uff0c\u7c7b\u624d\u80fd\u6b63\u5e38\u5de5\u4f5c\u3002\u53ef\u4ee5\u901a\u8fc7\u7c7b\u6784\u9020\u51fd\u6570\u5e94\u7528\u6b64\u6761\u4ef6\uff0c\u5e76\u4e14\u53ef\u4ee5\u963b\u6b62\u521b\u5efa\u65e0\u6cd5\u4f7f\u7528\u7684\u5bf9\u8c61\u3002<\/p>\n<\/li>\n<li>\n<p>Single responsibility: This principle is proposed in object-oriented design as one of the architectural principles. This principle is like the separation of concerns and states that an object must have one task and reason for the change.<br \/>\n\u5355\u4e00\u8d23\u4efb\uff1a\u6b64\u539f\u5219\u5728\u9762\u5411\u5bf9\u8c61\u8bbe\u8ba1\u4e2d\u4f5c\u4e3a\u67b6\u6784\u539f\u5219\u4e4b\u4e00\u63d0\u51fa\u3002\u6b64\u539f\u5219\u7c7b\u4f3c\u4e8e\u5173\u6ce8\u70b9\u5206\u79bb\uff0c\u5e76\u58f0\u660e\u5bf9\u8c61\u5fc5\u987b\u5177\u6709\u4e00\u4e2a\u66f4\u6539\u7684\u4efb\u52a1\u548c\u539f\u56e0\u3002<\/p>\n<\/li>\n<li>\n<p>DRY: The behavior related to a specific concept should not be given in several places. Failure to comply with this principle will cause all the code to change its behavior, increasing the probability of errors and bugs.<br \/>\nDRY\uff1a\u4e0e\u7279\u5b9a\u6982\u5ff5\u76f8\u5173\u7684\u884c\u4e3a\u4e0d\u5e94\u5728\u591a\u4e2a\u5730\u65b9\u7ed9\u51fa\u3002\u4e0d\u9075\u5b88\u6b64\u539f\u5219\u5c06\u5bfc\u81f4\u6240\u6709\u4ee3\u7801\u6539\u53d8\u5176\u884c\u4e3a\uff0c\u4ece\u800c\u589e\u52a0\u9519\u8bef\u548c\u9519\u8bef\u7684\u53ef\u80fd\u6027\u3002<\/p>\n<\/li>\n<li>\n<p>Persistence ignorance: Different business models in data sources should be able to store regardless of the type. These models are often called Plain Old CLR Object (POCO)s in .NET. This is because the storage resource can change over time (for example, from SQL Server to Azure Cosmos DB), and this should not affect the rest of the sections. Some signs of violation of this principle can be introduced as the following:<br \/>\n\u6301\u4e45\u6027\u65e0\u77e5\uff1a\u6570\u636e\u6e90\u4e2d\u7684\u4e0d\u540c\u4e1a\u52a1\u6a21\u578b\u5e94\u8be5\u80fd\u591f\u5b58\u50a8\uff0c\u800c\u4e0d\u7ba1\u7c7b\u578b\u5982\u4f55\u3002\u8fd9\u4e9b\u6a21\u578b\u5728 .NET \u4e2d\u901a\u5e38\u79f0\u4e3a\u666e\u901a\u65e7 CLR \u5bf9\u8c61 \uff08POCO\uff09\u3002\u8fd9\u662f\u56e0\u4e3a\u5b58\u50a8\u8d44\u6e90\u53ef\u80fd\u4f1a\u968f\u65f6\u95f4\u800c\u53d8\u5316\uff08\u4f8b\u5982\uff0c\u4ece SQL Server \u66f4\u6539\u4e3a Azure Cosmos DB\uff09\uff0c\u8fd9\u4e0d\u5e94\u5f71\u54cd\u5176\u4f59\u90e8\u5206\u3002\u8fdd\u53cd\u6b64\u539f\u5219\u7684\u4e00\u4e9b\u8ff9\u8c61\u53ef\u4ee5\u5f15\u5165\u5982\u4e0b\uff1a<\/p>\n<p>Binding to a specific parent class<br \/>\n\u7ed1\u5b9a\u5230\u7279\u5b9a\u7684\u7236\u7c7b<\/p>\n<p>The requirement to implement a specific interface<br \/>\n\u5b9e\u73b0\u7279\u5b9a\u63a5\u53e3\u7684\u8981\u6c42 <\/p>\n<p>Requiring the class to store itself (as in Active Record)<br \/>\n\u8981\u6c42\u7c7b\u5b58\u50a8\u81ea\u8eab\uff08\u5982 Active Record \u4e2d\uff09<\/p>\n<p>The presence of mandatory parametric constructors<br \/>\n\u5b58\u5728\u5f3a\u5236\u6027\u53c2\u6570\u6784\u9020\u51fd\u6570<\/p>\n<p>The presence of virtual features in the class<br \/>\n\u7c7b\u4e2d\u5b58\u5728\u865a\u62df\u7279\u5f81<\/p>\n<p>The presence of unique attributes related to storage technology<br \/>\n\u5b58\u5728\u4e0e\u5b58\u50a8\u6280\u672f\u76f8\u5173\u7684\u72ec\u7279\u5c5e\u6027<\/p>\n<p>The preceding cases are introduced as violations of the principle of persistence ignorance because these cases often create a dependency between models and storage technology, making it difficult to adapt to new storage technology in the future.<br \/>\n\u4e0a\u8ff0\u60c5\u51b5\u8fdd\u53cd\u4e86\u6301\u4e45\u5316\u65e0\u77e5\u539f\u5219\uff0c\u56e0\u4e3a\u8fd9\u4e9b\u60c5\u51b5\u901a\u5e38\u4f1a\u5728\u6a21\u578b\u548c\u5b58\u50a8\u6280\u672f\u4e4b\u95f4\u4ea7\u751f\u4f9d\u8d56\u5173\u7cfb\uff0c\u4f7f\u5176\u5c06\u6765\u96be\u4ee5\u9002\u5e94\u65b0\u7684\u5b58\u50a8\u6280\u672f\u3002<\/p>\n<\/li>\n<li>\n<p>Bounded contexts: A more significant problem can be divided into smaller conceptual sub-problems. In other words, each sub-problem represents a context that is independent of other contexts. Communication between different contexts is established through programming interfaces. Any communication or data source shared between contexts should be avoided, as it will cause tight coupling between contexts.<br \/>\n\u6709\u754c\u4e0a\u4e0b\u6587\uff1a\u66f4\u91cd\u8981\u7684\u95ee\u9898\u53ef\u4ee5\u5212\u5206\u4e3a\u66f4\u5c0f\u7684\u6982\u5ff5\u5b50\u95ee\u9898\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u6bcf\u4e2a\u5b50\u95ee\u9898\u90fd\u4ee3\u8868\u4e00\u4e2a\u72ec\u7acb\u4e8e\u5176\u4ed6\u4e0a\u4e0b\u6587\u7684\u4e0a\u4e0b\u6587\u3002\u4e0d\u540c\u4e0a\u4e0b\u6587\u4e4b\u95f4\u7684\u901a\u4fe1\u662f\u901a\u8fc7\u7f16\u7a0b\u63a5\u53e3\u5efa\u7acb\u7684\u3002\u5e94\u907f\u514d\u5728\u4e0a\u4e0b\u6587\u4e4b\u95f4\u5171\u4eab\u4efb\u4f55\u901a\u4fe1\u6216\u6570\u636e\u6e90\uff0c\u56e0\u4e3a\u8fd9\u4f1a\u5bfc\u81f4\u4e0a\u4e0b\u6587\u4e4b\u95f4\u7d27\u5bc6\u8026\u5408\u3002<\/p>\n<\/li>\n<\/ul>\n<h2>What are design patterns<\/h2>\n<h2>\u4ec0\u4e48\u662f\u8bbe\u8ba1\u6a21\u5f0f<\/h2>\n<p>As can be seen from the title of the word &quot;design pattern&quot;, it is simply a pattern that can be used to solve an upcoming problem. This means that the completed design is not a finished design that can be directly converted into source code or machine code. During the design and production of software, we face various problems in design and implementation, which are repetitive. Therefore, the answer to these often has a fixed format. For example, developing a feature to send messages to the end user may be necessary for software production. Therefore, a suitable infrastructure must be designed and implemented for this requirement. On the other hand, there are different ways to send messages to end users, such as via email, SMS, and so on. The mentioned problem has fixed generalities in most software, and the answer often has a fixed design and format.<br \/>\n\u4ece\u201c\u8bbe\u8ba1\u6a21\u5f0f\u201d\u8fd9\u4e2a\u8bcd\u7684\u6807\u9898\u53ef\u4ee5\u770b\u51fa\uff0c\u5b83\u53ea\u662f\u4e00\u79cd\u53ef\u4ee5\u7528\u6765\u89e3\u51b3\u5373\u5c06\u5230\u6765\u7684\u95ee\u9898\u7684\u6a21\u5f0f\u3002\u8fd9\u610f\u5473\u7740\u5b8c\u6210\u7684\u8bbe\u8ba1\u4e0d\u662f\u53ef\u4ee5\u76f4\u63a5\u8f6c\u6362\u4e3a\u6e90\u4ee3\u7801\u6216\u673a\u5668\u4ee3\u7801\u7684\u5df2\u5b8c\u6210\u8bbe\u8ba1\u3002\u5728\u8f6f\u4ef6\u7684\u8bbe\u8ba1\u548c\u751f\u4ea7\u8fc7\u7a0b\u4e2d\uff0c\u6211\u4eec\u5728\u8bbe\u8ba1\u548c\u5b9e\u73b0\u4e2d\u9762\u4e34\u5404\u79cd\u95ee\u9898\uff0c\u8fd9\u4e9b\u95ee\u9898\u662f\u91cd\u590d\u7684\u3002\u56e0\u6b64\uff0c\u8fd9\u4e9b\u95ee\u9898\u7684\u7b54\u6848\u901a\u5e38\u5177\u6709\u56fa\u5b9a\u7684\u683c\u5f0f\u3002\u4f8b\u5982\uff0c\u5f00\u53d1\u4e00\u9879\u529f\u80fd\u4ee5\u5411\u6700\u7ec8\u7528\u6237\u53d1\u9001\u6d88\u606f\u5bf9\u4e8e\u8f6f\u4ef6\u751f\u4ea7\u53ef\u80fd\u662f\u5fc5\u8981\u7684\u3002\u56e0\u6b64\uff0c\u5fc5\u987b\u9488\u5bf9\u6b64\u8981\u6c42\u8bbe\u8ba1\u548c\u5b9e\u65bd\u5408\u9002\u7684\u57fa\u7840\u8bbe\u65bd\u3002\u53e6\u4e00\u65b9\u9762\uff0c\u6709\u591a\u79cd\u65b9\u6cd5\u53ef\u4ee5\u5411\u6700\u7ec8\u7528\u6237\u53d1\u9001\u6d88\u606f\uff0c\u4f8b\u5982\u901a\u8fc7\u7535\u5b50\u90ae\u4ef6\u3001SMS \u7b49\u3002\u4e0a\u8ff0\u95ee\u9898\u5728\u5927\u591a\u6570\u8f6f\u4ef6\u4e2d\u5177\u6709\u56fa\u5b9a\u7684\u901a\u7528\u6027\uff0c\u800c\u7b54\u6848\u901a\u5e38\u5177\u6709\u56fa\u5b9a\u7684\u8bbe\u8ba1\u548c\u683c\u5f0f\u3002<\/p>\n<p>A design pattern is a general, repeatable solution to common problems in software design. Therefore, if we encounter a new issue during software production, there may be no pattern introduced for that, and we need to solve it without the help of existing practices. This needs to be solved by designing a correct structure.<\/p>\n<p>\u8bbe\u8ba1\u6a21\u5f0f\u662f\u9488\u5bf9\u8f6f\u4ef6\u8bbe\u8ba1\u4e2d\u5e38\u89c1\u95ee\u9898\u7684\u901a\u7528\u3001\u53ef\u91cd\u590d\u7684\u89e3\u51b3\u65b9\u6848\u3002\u56e0\u6b64\uff0c\u5982\u679c\u6211\u4eec\u5728\u8f6f\u4ef6\u751f\u4ea7\u8fc7\u7a0b\u4e2d\u9047\u5230\u65b0\u7684\u95ee\u9898\uff0c\u53ef\u80fd\u6ca1\u6709\u5f15\u5165\u4efb\u4f55\u6a21\u5f0f\uff0c\u6211\u4eec\u9700\u8981\u5728\u6ca1\u6709\u73b0\u6709\u5b9e\u8df5\u5e2e\u52a9\u7684\u60c5\u51b5\u4e0b\u89e3\u51b3\u5b83\u3002\u8fd9\u9700\u8981\u901a\u8fc7\u8bbe\u8ba1\u6b63\u786e\u7684\u7ed3\u6784\u6765\u89e3\u51b3\u3002<\/p>\n<p>Using design patterns has several advantages:<br \/>\n\u4f7f\u7528\u8bbe\u8ba1\u6a21\u5f0f\u6709\u51e0\u4e2a\u4f18\u70b9\uff1a<\/p>\n<ul>\n<li>\n<p>Increasing scalability<br \/>\n\u63d0\u9ad8\u53ef\u6269\u5c55\u6027<\/p>\n<\/li>\n<li>\n<p>Increasing expandability<br \/>\n\u63d0\u9ad8\u53ef\u6269\u5c55\u6027<\/p>\n<\/li>\n<li>\n<p>Increased flexibility<br \/>\n\u63d0\u9ad8\u7075\u6d3b\u6027<\/p>\n<\/li>\n<li>\n<p>Increase the speed of development<br \/>\n\u63d0\u9ad8\u5f00\u53d1\u901f\u5ea6<\/p>\n<\/li>\n<li>\n<p>Reduce errors and problems<br \/>\n\u51cf\u5c11\u9519\u8bef\u548c\u95ee\u9898<\/p>\n<\/li>\n<li>\n<p>Reducing the amount of coding<br \/>\n\u51cf\u5c11\u7f16\u7801\u91cf<\/p>\n<\/li>\n<\/ul>\n<p>The important thing about design patterns is that they are not a part of the architecture of software systems, and they only provide the correct method of object-oriented coding. You can choose and implement the right way to solve a problem.<br \/>\n\u8bbe\u8ba1\u6a21\u5f0f\u7684\u91cd\u8981\u4e00\u70b9\u662f\uff0c\u5b83\u4eec\u4e0d\u662f\u8f6f\u4ef6\u7cfb\u7edf\u67b6\u6784\u7684\u4e00\u90e8\u5206\uff0c\u5b83\u4eec\u53ea\u63d0\u4f9b\u6b63\u786e\u7684\u9762\u5411\u5bf9\u8c61\u7f16\u7801\u65b9\u6cd5\u3002\u60a8\u53ef\u4ee5\u9009\u62e9\u5e76\u5b9e\u65bd\u6b63\u786e\u7684\u65b9\u6cd5\u6765\u89e3\u51b3\u95ee\u9898\u3002<\/p>\n<h2>GoF design patterns<\/h2>\n<h2>GoF \u8bbe\u8ba1\u6a21\u5f0f<\/h2>\n<p>In the past years, Christopher Alexander introduced the design pattern. He was an architect and used patterns to build buildings. This attitude and thinking of Alexander made Eric Gama use design patterns to develop and produce software in his doctoral dissertation. After a short period, Chard Helm started working with Eric Gama. Later, John Vlissides and Ralph Johnson also joined this group. The initial idea was to publish the design patterns as an article, and due to its length, the full text was published as a book. This four-person group, which is also called Gang of Four (GoF), published a book called \u201cElements of Reusable Object-Oriented Software\u201d, and they classified and presented 23 different design patterns in the form of 3 different categories (structural, behavioral, and creational). They tried to categorize it from the user's perspective. To fully present this, the GoF group developed a general structure to introduce the design patterns, which consisted of the following sections:<\/p>\n<p>\u5728\u8fc7\u53bb\u7684\u51e0\u5e74\u91cc\uff0cChristopher Alexander \u5f15\u5165\u4e86\u8bbe\u8ba1\u6a21\u5f0f\u3002\u4ed6\u662f\u4e00\u540d\u5efa\u7b51\u5e08\uff0c\u4f7f\u7528\u56fe\u6848\u6765\u5efa\u9020\u5efa\u7b51\u7269\u3002Alexander \u7684\u8fd9\u79cd\u6001\u5ea6\u548c\u601d\u8003\u4f7f Eric Gama \u5728\u4ed6\u7684\u535a\u58eb\u8bba\u6587\u4e2d\u4f7f\u7528\u8bbe\u8ba1\u6a21\u5f0f\u6765\u5f00\u53d1\u548c\u751f\u4ea7\u8f6f\u4ef6\u3002\u4e0d\u4e45\u4e4b\u540e\uff0cChard Helm \u5f00\u59cb\u4e0e Eric Gama \u5408\u4f5c\u3002\u540e\u6765\uff0cJohn Vlissides \u548c Ralph Johnson \u4e5f\u52a0\u5165\u4e86\u8fd9\u4e2a\u56e2\u4f53\u3002\u6700\u521d\u7684\u60f3\u6cd5\u662f\u5c06\u8bbe\u8ba1\u6a21\u5f0f\u4f5c\u4e3a\u4e00\u7bc7\u6587\u7ae0\u53d1\u5e03\uff0c\u7531\u4e8e\u5b83\u7684\u957f\u5ea6\uff0c\u5168\u6587\u88ab\u4f5c\u4e3a\u4e00\u672c\u4e66\u53d1\u5e03\u3002\u8fd9\u4e2a\u56db\u4eba\u5c0f\u7ec4\uff0c\u4e5f\u88ab\u79f0\u4e3a Gang of Four \uff08GoF\uff09\uff0c\u51fa\u7248\u4e86\u4e00\u672c\u540d\u4e3a\u300aElements of Reusable Object-Oriented Software\u300b\u7684\u4e66\uff0c\u4ed6\u4eec\u4ee5 3 \u4e2a\u4e0d\u540c\u7c7b\u522b\uff08\u7ed3\u6784\u3001\u884c\u4e3a\u548c\u521b\u5efa\uff09\u7684\u5f62\u5f0f\u5206\u7c7b\u548c\u5448\u73b0\u4e86 23 \u79cd\u4e0d\u540c\u7684\u8bbe\u8ba1\u6a21\u5f0f\u3002\u4ed6\u4eec\u8bd5\u56fe\u4ece\u7528\u6237\u7684\u89d2\u5ea6\u5bf9\u5176\u8fdb\u884c\u5206\u7c7b\u3002\u4e3a\u4e86\u5145\u5206\u5448\u73b0\u8fd9\u4e00\u70b9\uff0cGoF \u5c0f\u7ec4\u5f00\u53d1\u4e86\u4e00\u4e2a\u901a\u7528\u7ed3\u6784\u6765\u4ecb\u7ecd\u8bbe\u8ba1\u6a21\u5f0f\uff0c\u5176\u4e2d\u5305\u62ec\u4ee5\u4e0b\u90e8\u5206\uff1a<\/p>\n<ul>\n<li>\n<p>Name and Classification: It shows the design pattern's name and specifies each design pattern's category.<br \/>\nName and Classification\uff1a\u5b83\u663e\u793a\u8bbe\u8ba1\u6a21\u5f0f\u7684\u540d\u79f0\u5e76\u6307\u5b9a\u6bcf\u4e2a\u8bbe\u8ba1\u6a21\u5f0f\u7684\u7c7b\u522b\u3002<\/p>\n<\/li>\n<li>\n<p>Also Known As: If other names know the design pattern, they are introduced in this section.<br \/>\n\u4e5f\u79f0\u4e3a\uff1a\u5982\u679c\u5176\u4ed6\u540d\u79f0\u77e5\u9053\u8bbe\u8ba1\u6a21\u5f0f\uff0c\u5219\u672c\u8282\u5c06\u4ecb\u7ecd\u5b83\u4eec\u3002<\/p>\n<\/li>\n<li>\n<p>Intent: This section gives brief explanations about the design pattern.<br \/>\nIntent\uff1a\u672c\u8282\u63d0\u4f9b\u6709\u5173\u8bbe\u8ba1\u6a21\u5f0f\u7684\u7b80\u8981\u8bf4\u660e\u3002<\/p>\n<\/li>\n<li>\n<p>Motivation, Structure, Implementation, and Sample Code: A description of the problem, main structure, implementation steps, and the source code of design patterns are presented.<br \/>\n\u52a8\u673a\u3001\u7ed3\u6784\u3001\u5b9e\u73b0\u548c\u793a\u4f8b\u4ee3\u7801\uff1a\u63d0\u4f9b\u4e86\u95ee\u9898\u63cf\u8ff0\u3001\u4e3b\u8981\u7ed3\u6784\u3001\u5b9e\u73b0\u6b65\u9aa4\u548c\u8bbe\u8ba1\u6a21\u5f0f\u7684\u6e90\u4ee3\u7801\u3002<\/p>\n<\/li>\n<li>\n<p>Participants: This section introduces and describes different participants (in terms of classes and objects involved) in the design pattern.<br \/>\n\u53c2\u4e0e\u8005\uff1a\u672c\u8282\u4ecb\u7ecd\u548c\u63cf\u8ff0\u8bbe\u8ba1\u6a21\u5f0f\u4e2d\u7684\u4e0d\u540c\u53c2\u4e0e\u8005\uff08\u6839\u636e\u6d89\u53ca\u7684\u7c7b\u548c\u5bf9\u8c61\uff09\u3002<\/p>\n<\/li>\n<li>\n<p>Notes: Significant points are given in this section regarding the design and implementation of each design pattern.<br \/>\n\u6ce8\u610f\uff1a\u672c\u8282\u4e2d\u7ed9\u51fa\u4e86\u6709\u5173\u6bcf\u4e2a\u8bbe\u8ba1\u6a21\u5f0f\u7684\u8bbe\u8ba1\u548c\u5b9e\u73b0\u7684\u91cd\u8981\u8981\u70b9\u3002<\/p>\n<\/li>\n<li>\n<p>Consequences: Advantages and disadvantages of the discussed design pattern are given.<br \/>\n\u7ed3\u679c\uff1a\u7ed9\u51fa\u4e86\u6240\u8ba8\u8bba\u7684\u8bbe\u8ba1\u6a21\u5f0f\u7684\u4f18\u7f3a\u70b9\u3002<\/p>\n<\/li>\n<li>\n<p>Applicability: Places, where the discussed design pattern can be helpful, are briefly stated.<br \/>\n\u9002\u7528\u6027\uff1a\u7b80\u8981\u8bf4\u660e\u6240\u8ba8\u8bba\u7684\u8bbe\u8ba1\u6a21\u5f0f\u53ef\u80fd\u6709\u7528\u7684\u4f4d\u7f6e\u3002<\/p>\n<\/li>\n<li>\n<p>Related Patterns: The relationship of each design pattern with other design patterns is mentioned.<br \/>\nRelated Patterns\uff1a\u63d0\u5230\u4e86\u6bcf\u79cd\u8bbe\u8ba1\u6a21\u5f0f\u4e0e\u5176\u4ed6\u8bbe\u8ba1\u6a21\u5f0f\u7684\u5173\u7cfb\u3002<\/p>\n<\/li>\n<\/ul>\n<p>The 23 presented patterns can be divided in the form of the following table in terms of scope (whether the pattern is applied to the class or its objects) and purpose (what the pattern does):<br \/>\n\u63d0\u4f9b\u7684 23 \u79cd\u6a21\u5f0f\u53ef\u4ee5\u6309\u8303\u56f4\uff08\u6a21\u5f0f\u662f\u5e94\u7528\u4e8e\u7c7b\u8fd8\u662f\u5176\u5bf9\u8c61\uff09\u548c\u76ee\u7684\uff08\u6a21\u5f0f\u7684\u4f5c\u7528\uff09\u4ee5\u4e0b\u8868\u7684\u5f62\u5f0f\u8fdb\u884c\u5212\u5206\uff1a<\/p>\n<table>\n<thead>\n<tr>\n<th><\/th>\n<th>Behavioral<\/th>\n<th>Structural<\/th>\n<th>Creational<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Class<\/td>\n<td>Interpreter\u3001Template Method<\/td>\n<td>Class Adapter<\/td>\n<td>Factory Method<\/td>\n<\/tr>\n<tr>\n<td>Object<\/td>\n<td>Chain of Responsibility\u3001Command\u3001Iterator\u3001Mediator\u3001Memento\u3001Observer\u3001State\u3001Strategy\u3001Visitor<\/td>\n<td>Object Adapter\u3001Bridge\u3001Composite\u3001Decorator\u3001Fa\u00e7ade\u3001Flyweight\u3001Proxy<\/td>\n<td>Abstract Factory\u3001Builder Prototype\u3001Singleton<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 1.1: Classification of GoF Design Patterns<br \/>\n\u8868 1.1\uff1aGoF \u8bbe\u8ba1\u6a21\u5f0f\u7684\u5206\u7c7b<\/p>\n<p>Every design pattern has four essential features as follows:<br \/>\n\u6bcf\u4e2a\u8bbe\u8ba1\u6a21\u5f0f\u90fd\u6709\u56db\u4e2a\u57fa\u672c\u7279\u5f81\uff0c\u5982\u4e0b\u6240\u793a\uff1a<\/p>\n<ul>\n<li>\n<p>Name: Every template must have a name. The name of the design pattern should be such that the application, problem, or solution provided can be reached from the name of the design pattern.<br \/>\n\u540d\u79f0\uff1a\u6bcf\u4e2a\u6a21\u677f\u90fd\u5fc5\u987b\u6709\u4e00\u4e2a\u540d\u79f0\u3002\u8bbe\u8ba1\u6a21\u5f0f\u7684\u540d\u79f0\u5e94\u4f7f\u6240\u63d0\u4f9b\u7684\u5e94\u7528\u7a0b\u5e8f\u3001\u95ee\u9898\u6216\u89e3\u51b3\u65b9\u6848\u53ef\u4ee5\u4ece\u8bbe\u8ba1\u6a21\u5f0f\u7684\u540d\u79f0\u4e2d\u8bbf\u95ee\u3002<\/p>\n<\/li>\n<li>\n<p>Problem: The problem indicates how the design pattern can be applied.<br \/>\n\u95ee\u9898\uff1a\u8be5\u95ee\u9898\u6307\u793a\u5982\u4f55\u5e94\u7528\u8bbe\u8ba1\u6a21\u5f0f\u3002<\/p>\n<\/li>\n<li>\n<p>Solution: It deals with the expression of the solution, the involved elements, and their relationships.<br \/>\n\u89e3\u51b3\u65b9\u6848\uff1a\u5b83\u5904\u7406\u89e3\u51b3\u65b9\u6848\u7684\u8868\u8fbe\u5f0f\u3001\u6d89\u53ca\u7684\u5143\u7d20\u53ca\u5176\u5173\u7cfb\u3002<\/p>\n<\/li>\n<li>\n<p>Consequences: It expresses the results, advantages, disadvantages, and effects of using the design pattern.<br \/>\n\u540e\u679c\uff1a\u5b83\u8868\u793a\u4f7f\u7528\u8bbe\u8ba1\u6a21\u5f0f\u7684\u7ed3\u679c\u3001\u4f18\u70b9\u3001\u7f3a\u70b9\u548c\u6548\u679c\u3002<\/p>\n<\/li>\n<\/ul>\n<p>The relationship of all these 23 patterns can be seen in the following figure:<\/p>\n<p><img decoding=\"async\" src=\"\/net7designpatternsindepth\/0109.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 1.9: Relationships of GoF Design Patterns<br \/>\n\u56fe 1.9\uff1a GoF \u8bbe\u8ba1\u6a21\u5f0f\u7684\u5173\u7cfb<\/p>\n<p>The design patterns provided by GoF are not the only design patterns available. Martin Fowler has also introduced a series of other design patterns with a different look at software production problems called Patterns of Enterprise Application Architecture (PofEAA). He tried to introduce suitable solutions for everyday problems in producing enterprise software. Although there is a rea meter and criteria for using design patterns, a small software may need to use PofEAA design patterns. Martin Fowler has also divided the provided design patterns into different categories, which include the following:<\/p>\n<p>GoF \u63d0\u4f9b\u7684\u8bbe\u8ba1\u6a21\u5f0f\u5e76\u4e0d\u662f\u552f\u4e00\u53ef\u7528\u7684\u8bbe\u8ba1\u6a21\u5f0f\u3002Martin Fowler \u8fd8\u5f15\u5165\u4e86\u4e00\u7cfb\u5217\u5176\u4ed6\u8bbe\u8ba1\u6a21\u5f0f\uff0c\u8fd9\u4e9b\u6a21\u5f0f\u5bf9\u8f6f\u4ef6\u751f\u4ea7\u95ee\u9898\u6709\u7740\u4e0d\u540c\u7684\u770b\u6cd5\uff0c\u79f0\u4e3a\u4f01\u4e1a\u5e94\u7528\u7a0b\u5e8f\u67b6\u6784\u6a21\u5f0f \uff08PofEAA\uff09\u3002\u4ed6\u8bd5\u56fe\u4e3a\u751f\u4ea7\u4f01\u4e1a\u8f6f\u4ef6\u4e2d\u7684\u65e5\u5e38\u95ee\u9898\u5f15\u5165\u5408\u9002\u7684\u89e3\u51b3\u65b9\u6848\u3002\u5c3d\u7ba1\u4f7f\u7528\u8bbe\u8ba1\u6a21\u5f0f\u6709\u4e25\u683c\u7684\u6807\u51c6\u548c\u6807\u51c6\uff0c\u4f46\u5c0f\u578b\u8f6f\u4ef6\u53ef\u80fd\u9700\u8981\u4f7f\u7528 PofEAA \u8bbe\u8ba1\u6a21\u5f0f\u3002Martin Fowler \u8fd8\u5c06\u63d0\u4f9b\u7684\u8bbe\u8ba1\u6a21\u5f0f\u5206\u4e3a\u4e0d\u540c\u7684\u7c7b\u522b\uff0c\u5176\u4e2d\u5305\u62ec\uff1a<\/p>\n<ul>\n<li>Domain-logic patterns<br \/>\n\u57df\u903b\u8f91\u6a21\u5f0f<\/li>\n<li>Data-source architectural patterns<br \/>\n\u6570\u636e\u6e90\u67b6\u6784\u6a21\u5f0f<\/li>\n<li>Object-relational behavioral patterns<br \/>\n\u5bf9\u8c61\u5173\u7cfb\u884c\u4e3a\u6a21\u5f0f<\/li>\n<li>Object-relational structural patterns<br \/>\n\u5bf9\u8c61\u5173\u7cfb\u7ed3\u6784\u6a21\u5f0f<\/li>\n<li>Object-relational metadata-mapping patterns<br \/>\n\u5bf9\u8c61\u5173\u7cfb\u5143\u6570\u636e\u6620\u5c04\u6a21\u5f0f<\/li>\n<li>Web presentation patterns<br \/>\nWeb \u8868\u793a\u6a21\u5f0f<\/li>\n<li>Distribution patterns<br \/>\n\u5206\u5e03\u6a21\u5f0f<\/li>\n<li>Offline concurrency patterns<br \/>\n\u8131\u673a\u5e76\u53d1\u6a21\u5f0f<\/li>\n<li>Session-state patterns<br \/>\n\u4f1a\u8bdd\u72b6\u6001\u6a21\u5f0f<\/li>\n<li>Base patterns<br \/>\n\u57fa\u672c\u6a21\u5f0f<\/li>\n<\/ul>\n<p>In this chapter, an attempt has been made to explain GoF and PofEAA design patterns with a simple approach, along with practical examples.<br \/>\n\u5728\u672c\u7ae0\u4e2d\uff0c\u6211\u4eec\u5c1d\u8bd5\u7528\u7b80\u5355\u7684\u65b9\u6cd5\u89e3\u91ca GoF \u548c PofEAA \u8bbe\u8ba1\u6a21\u5f0f\uff0c\u5e76\u63d0\u4f9b\u4e86\u5b9e\u9645\u793a\u4f8b\u3002<\/p>\n<h2>Enterprise application and its design patterns<\/h2>\n<h2>\u4f01\u4e1a\u5e94\u7528\u7a0b\u5e8f\u53ca\u5176\u8bbe\u8ba1\u6a21\u5f0f<\/h2>\n<p>People construct types of different applications. Each of these has its challenges and complexities. For example, in one software, concurrency issues may be significant and critical, and in another category, the complexity of data structures might be necessary. The term enterprise application or information systems refers to systems in which we face the complexity of data processing and storage. To implement this software, special design patterns will be needed to manage business logic and data. It is important to understand that a series of design patterns can be useful for different types of software. However, a series will also be more suitable for enterprise applications.<\/p>\n<p>\u4eba\u4eec\u6784\u5efa\u4e0d\u540c\u7c7b\u578b\u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u6bcf\u4e00\u9879\u90fd\u6709\u5176\u6311\u6218\u548c\u590d\u6742\u6027\u3002\u4f8b\u5982\uff0c\u5728\u4e00\u4e2a\u8f6f\u4ef6\u4e2d\uff0c\u5e76\u53d1\u95ee\u9898\u53ef\u80fd\u662f\u91cd\u5927\u548c\u5173\u952e\u7684\uff0c\u800c\u5728\u53e6\u4e00\u4e2a\u7c7b\u522b\u4e2d\uff0c\u6570\u636e\u7ed3\u6784\u7684\u590d\u6742\u6027\u53ef\u80fd\u662f\u5fc5\u8981\u7684\u3002\u672f\u8bed\u4f01\u4e1a\u5e94\u7528\u7a0b\u5e8f\u6216\u4fe1\u606f\u7cfb\u7edf\u662f\u6307\u6211\u4eec\u9762\u4e34\u6570\u636e\u5904\u7406\u548c\u5b58\u50a8\u590d\u6742\u6027\u7684\u7cfb\u7edf\u3002\u8981\u5b9e\u73b0\u6b64\u8f6f\u4ef6\uff0c\u9700\u8981\u7279\u6b8a\u7684\u8bbe\u8ba1\u6a21\u5f0f\u6765\u7ba1\u7406\u4e1a\u52a1\u903b\u8f91\u548c\u6570\u636e\u3002\u4e86\u89e3\u4e00\u7cfb\u5217\u8bbe\u8ba1\u6a21\u5f0f\u5bf9\u4e8e\u4e0d\u540c\u7c7b\u578b\u7684\u8f6f\u4ef6\u975e\u5e38\u6709\u7528\uff0c\u8fd9\u4e00\u70b9\u5f88\u91cd\u8981\u3002\u4f46\u662f\uff0c\u7cfb\u5217\u4e5f\u5c06\u66f4\u9002\u5408\u4f01\u4e1a\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<p>Among the most famous enterprise applications, we can mention accounting software, toll payment, insurance, customer service, and so on. On the other hand, software such as text processors, operating systems, compilers, and even computer games are not part of the enterprise application category.<\/p>\n<p>\u5728\u6700\u8457\u540d\u7684\u4f01\u4e1a\u5e94\u7528\u7a0b\u5e8f\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u63d0\u5230\u4f1a\u8ba1\u8f6f\u4ef6\u3001\u901a\u884c\u8d39\u652f\u4ed8\u3001\u4fdd\u9669\u3001\u5ba2\u6237\u670d\u52a1\u7b49\u3002\u53e6\u4e00\u65b9\u9762\uff0c\u6587\u672c\u5904\u7406\u5668\u3001\u4f5c\u7cfb\u7edf\u3001\u7f16\u8bd1\u5668\u751a\u81f3\u8ba1\u7b97\u673a\u6e38\u620f\u7b49\u8f6f\u4ef6\u4e0d\u5c5e\u4e8e\u4f01\u4e1a\u5e94\u7528\u7a0b\u5e8f\u7c7b\u522b\u3002<\/p>\n<p>The important characteristic of enterprise applications is the durability of data. This data may be stored in data sources for years. The reason for the durability of these data will be needed at different times in different parts of the program at different steps of the process. During the lifetime of the data, we may encounter small and significant changes in operating systems, hardware, and compilers. The volume of data we face in an enterprise application is often large, and different databases will often be needed for storing them.<\/p>\n<p>\u4f01\u4e1a\u5e94\u7528\u7a0b\u5e8f\u7684\u91cd\u8981\u7279\u5f81\u662f\u6570\u636e\u7684\u6301\u4e45\u6027\u3002\u6b64\u6570\u636e\u53ef\u80fd\u4f1a\u5728\u6570\u636e\u6e90\u4e2d\u5b58\u50a8\u6570\u5e74\u3002\u8fd9\u4e9b\u6570\u636e\u6301\u4e45\u6027\u7684\u539f\u56e0\u5c06\u5728\u7a0b\u5e8f\u7684\u4e0d\u540c\u65f6\u95f4\u3001\u6d41\u7a0b\u7684\u4e0d\u540c\u6b65\u9aa4\u4e2d\u9700\u8981\u3002\u5728\u6570\u636e\u7684\u751f\u547d\u5468\u671f\u5185\uff0c\u6211\u4eec\u53ef\u80fd\u4f1a\u9047\u5230\u4f5c\u7cfb\u7edf\u3001\u786c\u4ef6\u548c\u7f16\u8bd1\u5668\u7684\u5fae\u5c0f\u800c\u91cd\u5927\u7684\u53d8\u5316\u3002\u6211\u4eec\u5728\u4f01\u4e1a\u5e94\u7528\u7a0b\u5e8f\u4e2d\u9762\u4e34\u7684\u6570\u636e\u91cf\u901a\u5e38\u5f88\u5927\uff0c\u5e76\u4e14\u901a\u5e38\u9700\u8981\u4e0d\u540c\u7684\u6570\u636e\u5e93\u6765\u5b58\u50a8\u8fd9\u4e9b\u6570\u636e\u3002<\/p>\n<p>When we have a lot of data and have to present it to the users, graphic interfaces and different pages will be needed. The users who use these pages are different from each other and have different knowledge levels of software and computers. Therefore, we will use different methods and procedures to provide users with better data.<\/p>\n<p>\u5f53\u6211\u4eec\u6709\u5927\u91cf\u6570\u636e\u5e76\u4e14\u5fc5\u987b\u5c06\u5176\u5448\u73b0\u7ed9\u7528\u6237\u65f6\uff0c\u5c06\u9700\u8981\u56fe\u5f62\u754c\u9762\u548c\u4e0d\u540c\u7684\u9875\u9762\u3002\u4f7f\u7528\u8fd9\u4e9b\u9875\u9762\u7684\u7528\u6237\u5f7c\u6b64\u4e0d\u540c\uff0c\u5e76\u4e14\u5bf9\u8f6f\u4ef6\u548c\u8ba1\u7b97\u673a\u7684\u77e5\u8bc6\u6c34\u5e73\u4e0d\u540c\u3002\u56e0\u6b64\uff0c\u6211\u4eec\u5c06\u4f7f\u7528\u4e0d\u540c\u7684\u65b9\u6cd5\u548c\u7a0b\u5e8f\u4e3a\u7528\u6237\u63d0\u4f9b\u66f4\u597d\u7684\u6570\u636e\u3002<\/p>\n<p>Enterprise application often needs to communicate with other software. Each software may have its technology stack. However, we face different interaction, communication, and software integration methods. Even at the level of business analysis, each software may have different analyses for a specific entity, leading to the emergence of different data structures. From another point of view, business logic can be complex, and it is very important to organize these effectively and change them over time.<\/p>\n<p>\u4f01\u4e1a\u5e94\u7528\u7a0b\u5e8f\u901a\u5e38\u9700\u8981\u4e0e\u5176\u4ed6\u8f6f\u4ef6\u901a\u4fe1\u3002\u6bcf\u4e2a\u8f6f\u4ef6\u90fd\u53ef\u80fd\u6709\u5176\u6280\u672f\u5806\u6808\u3002\u4f46\u662f\uff0c\u6211\u4eec\u9762\u4e34\u7740\u4e0d\u540c\u7684\u4ea4\u4e92\u3001\u901a\u4fe1\u548c\u8f6f\u4ef6\u96c6\u6210\u65b9\u6cd5\u3002\u5373\u4f7f\u5728\u4e1a\u52a1\u5206\u6790\u5c42\u9762\uff0c\u6bcf\u4e2a\u8f6f\u4ef6\u4e5f\u53ef\u80fd\u5bf9\u7279\u5b9a\u5b9e\u4f53\u6709\u4e0d\u540c\u7684\u5206\u6790\uff0c\u4ece\u800c\u5bfc\u81f4\u51fa\u73b0\u4e0d\u540c\u7684\u6570\u636e\u7ed3\u6784\u3002\u4ece\u53e6\u4e00\u4e2a\u89d2\u5ea6\u6765\u770b\uff0c\u4e1a\u52a1\u903b\u8f91\u53ef\u80fd\u5f88\u590d\u6742\uff0c\u6709\u6548\u5730\u7ec4\u7ec7\u8fd9\u4e9b\u903b\u8f91\u5e76\u968f\u7740\u65f6\u95f4\u7684\u63a8\u79fb\u6539\u53d8\u5b83\u4eec\u975e\u5e38\u91cd\u8981\u3002<\/p>\n<p>When the word enterprise application is used, a mentality arises that we are dealing with a big software. In reality, this is not correct. A small software can create more value than a large software for the end user. One of the ways to deal with a big problem is to break and divide it into smaller problems. When these smaller issues are solved, they will lead to the solution of the bigger problem. This principle is also true about large software.<\/p>\n<p>\u5f53\u4f7f\u7528\u4f01\u4e1a\u5e94\u7528\u7a0b\u5e8f\u8fd9\u4e2a\u8bcd\u65f6\uff0c\u5c31\u4f1a\u4ea7\u751f\u4e00\u79cd\u5fc3\u6001\uff0c\u5373\u6211\u4eec\u6b63\u5728\u5904\u7406\u4e00\u4e2a\u5927\u578b\u8f6f\u4ef6\u3002\u5b9e\u9645\u4e0a\uff0c\u8fd9\u662f\u4e0d\u6b63\u786e\u7684\u3002\u5c0f\u578b\u8f6f\u4ef6\u53ef\u4ee5\u6bd4\u5927\u578b\u8f6f\u4ef6\u4e3a\u6700\u7ec8\u7528\u6237\u521b\u9020\u66f4\u591a\u4ef7\u503c\u3002\u5904\u7406\u5927\u95ee\u9898\u7684\u65b9\u6cd5\u4e4b\u4e00\u662f\u5c06\u5176\u5206\u89e3\u5e76\u5212\u5206\u4e3a\u8f83\u5c0f\u7684\u95ee\u9898\u3002\u5f53\u8fd9\u4e9b\u8f83\u5c0f\u7684\u95ee\u9898\u5f97\u5230\u89e3\u51b3\u65f6\uff0c\u5b83\u4eec\u5c06\u5bfc\u81f4\u66f4\u5927\u95ee\u9898\u7684\u89e3\u51b3\u3002\u6b64\u539f\u5219\u4e5f\u9002\u7528\u4e8e\u5927\u578b\u8f6f\u4ef6\u3002<\/p>\n<h2>Different types of enterprise applications<\/h2>\n<h2>\u4e0d\u540c\u7c7b\u578b\u7684\u4f01\u4e1a\u5e94\u7528\u7a0b\u5e8f<\/h2>\n<p>It should always be kept in mind that every enterprise application has its own challenges and complexities. Therefore, one solution can be generalized for types of enterprise applications. Consider the following two examples:<\/p>\n<p>\u5e94\u59cb\u7ec8\u7262\u8bb0\uff0c\u6bcf\u4e2a\u4f01\u4e1a\u5e94\u7528\u7a0b\u5e8f\u90fd\u6709\u81ea\u5df1\u7684\u6311\u6218\u548c\u590d\u6742\u6027\u3002\u56e0\u6b64\uff0c\u5bf9\u4e8e\u4f01\u4e1a\u5e94\u7528\u7a0b\u5e8f\u7c7b\u578b\uff0c\u53ef\u4ee5\u901a\u7528\u5316\u4e00\u79cd\u89e3\u51b3\u65b9\u6848\u3002\u8bf7\u8003\u8651\u4ee5\u4e0b\u4e24\u4e2a\u793a\u4f8b\uff1a<\/p>\n<p>Example 1: In an online selling software, we face many concurrent users. In this case, the proposed solution should have good scalability in addition to the effective use of resources so that with the help of hardware enhancement, the volume of incoming requests can increase the volume of supported concurrent users. In this type of software, the end user can efficiently work with it, so it will be necessary to design a web application that can run on most browsers.<\/p>\n<p>\u793a\u4f8b 1\uff1a\u5728\u5728\u7ebf\u9500\u552e\u8f6f\u4ef6\u4e2d\uff0c\u6211\u4eec\u9762\u4e34\u8bb8\u591a\u5e76\u53d1\u7528\u6237\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u9664\u4e86\u6709\u6548\u5229\u7528\u8d44\u6e90\u5916\uff0c\u6240\u63d0\u51fa\u7684\u89e3\u51b3\u65b9\u6848\u8fd8\u5e94\u5177\u6709\u826f\u597d\u7684\u53ef\u6269\u5c55\u6027\uff0c\u4ee5\u4fbf\u5728\u786c\u4ef6\u589e\u5f3a\u7684\u5e2e\u52a9\u4e0b\uff0c\u4f20\u5165\u8bf7\u6c42\u7684\u6570\u91cf\u53ef\u4ee5\u589e\u52a0\u652f\u6301\u7684\u5e76\u53d1\u7528\u6237\u7684\u6570\u91cf\u3002\u5728\u8fd9\u79cd\u7c7b\u578b\u7684\u8f6f\u4ef6\u4e2d\uff0c\u6700\u7ec8\u7528\u6237\u53ef\u4ee5\u6709\u6548\u5730\u4f7f\u7528\u5b83\uff0c\u56e0\u6b64\u6709\u5fc5\u8981\u8bbe\u8ba1\u4e00\u4e2a\u53ef\u4ee5\u5728\u5927\u591a\u6570\u6d4f\u89c8\u5668\u4e0a\u8fd0\u884c\u7684 Web \u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<p>Example 2: We may face software in which the volume of concurrent users is low, but the complexity of the business is high. For these systems, more complex graphical interfaces will be needed, which is necessary to manage more complex transactions.<\/p>\n<p>\u793a\u4f8b 2\uff1a\u6211\u4eec\u53ef\u80fd\u9047\u5230\u5e76\u53d1\u7528\u6237\u91cf\u8f83\u4f4e\u4f46\u4e1a\u52a1\u590d\u6742\u6027\u8f83\u9ad8\u7684\u8f6f\u4ef6\u3002\u5bf9\u4e8e\u8fd9\u4e9b\u7cfb\u7edf\uff0c\u5c06\u9700\u8981\u66f4\u590d\u6742\u7684\u56fe\u5f62\u754c\u9762\uff0c\u8fd9\u5bf9\u4e8e\u7ba1\u7406\u66f4\u590d\u6742\u7684\u4e8b\u52a1\u662f\u5fc5\u8981\u7684\u3002<\/p>\n<p>As evident in the preceding two examples, having a fixed architectural design for every type of enterprise software will not be possible. As mentioned before, the choice of architecture depends on the precise understanding of the problem.<\/p>\n<p>\u4ece\u524d\u9762\u7684\u4e24\u4e2a\u4f8b\u5b50\u4e2d\u53ef\u4ee5\u660e\u663e\u770b\u51fa\uff0c\u4e0d\u53ef\u80fd\u4e3a\u6bcf\u79cd\u7c7b\u578b\u7684\u4f01\u4e1a\u8f6f\u4ef6\u90fd\u91c7\u7528\u56fa\u5b9a\u7684\u67b6\u6784\u8bbe\u8ba1\u3002\u5982\u524d\u6240\u8ff0\uff0c\u67b6\u6784\u7684\u9009\u62e9\u53d6\u51b3\u4e8e\u5bf9\u95ee\u9898\u7684\u7cbe\u786e\u7406\u89e3\u3002<\/p>\n<p>One of the important points in dealing with enterprise applications and their architecture is to pay attention to efficiency, which can be different among teams. One team may pay attention to the performance issues from the beginning, and another may prefer to produce the software first and then identify and fix performance issues by monitoring various metrics. At the same time, a team might use a combination of these two methods. Whichever method is used to improve performance, the following factors are usually important to address:<\/p>\n<p>\u5904\u7406\u4f01\u4e1a\u5e94\u7528\u7a0b\u5e8f\u53ca\u5176\u67b6\u6784\u7684\u91cd\u8981\u4e00\u70b9\u662f\u5173\u6ce8\u6548\u7387\uff0c\u8fd9\u53ef\u80fd\u56e0\u56e2\u961f\u800c\u5f02\u3002\u4e00\u4e2a\u56e2\u961f\u53ef\u80fd\u4ece\u4e00\u5f00\u59cb\u5c31\u5173\u6ce8\u6027\u80fd\u95ee\u9898\uff0c\u800c\u53e6\u4e00\u4e2a\u56e2\u961f\u53ef\u80fd\u66f4\u613f\u610f\u5148\u751f\u4ea7\u8f6f\u4ef6\uff0c\u7136\u540e\u901a\u8fc7\u76d1\u63a7\u5404\u79cd\u6307\u6807\u6765\u8bc6\u522b\u548c\u4fee\u590d\u6027\u80fd\u95ee\u9898\u3002\u540c\u65f6\uff0c\u56e2\u961f\u53ef\u80fd\u4f1a\u7ed3\u5408\u4f7f\u7528\u8fd9\u4e24\u79cd\u65b9\u6cd5\u3002\u65e0\u8bba\u4f7f\u7528\u54ea\u79cd\u65b9\u6cd5\u63d0\u9ad8\u6027\u80fd\uff0c\u901a\u5e38\u90fd\u9700\u8981\u89e3\u51b3\u4ee5\u4e0b\u56e0\u7d20\uff1a<\/p>\n<ul>\n<li>\n<p>Response time: The time it takes to process a request and return the appropriate response to the user.<br \/>\n\u54cd\u5e94\u65f6\u95f4\uff1a\u5904\u7406\u8bf7\u6c42\u5e76\u5c06\u9002\u5f53\u7684\u54cd\u5e94\u8fd4\u56de\u7ed9\u7528\u6237\u6240\u9700\u7684\u65f6\u95f4\u3002<\/p>\n<\/li>\n<li>\n<p>Responsiveness: For example, suppose the user is uploading a file. The response rate will be better if the user can work with the software during the upload operation. Another mode is that the user has to wait while performing the upload operation. In this case, the response rate will be equal to the time rate.<br \/>\n\u54cd\u5e94\u80fd\u529b\uff1a\u4f8b\u5982\uff0c\u5047\u8bbe\u7528\u6237\u6b63\u5728\u4e0a\u4f20\u6587\u4ef6\u3002\u5982\u679c\u7528\u6237\u53ef\u4ee5\u5728\u4e0a\u4f20\u4f5c\u671f\u95f4\u4f7f\u7528\u8be5\u8f6f\u4ef6\uff0c\u5219\u54cd\u5e94\u7387\u4f1a\u66f4\u597d\u3002\u53e6\u4e00\u79cd\u6a21\u5f0f\u662f\u7528\u6237\u5728\u6267\u884c\u4e0a\u4f20\u4f5c\u65f6\u5fc5\u987b\u7b49\u5f85\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u54cd\u5e94\u7387\u5c06\u7b49\u4e8e\u65f6\u95f4\u7387\u3002<\/p>\n<\/li>\n<li>\n<p>Latency: The minimum time it takes to receive any response. For example, suppose we are connected to another system through Remote Desktop. The time it takes for the appropriate request and response to move through the network and reach us will indicate the delay rate.<br \/>\nLatency\uff08\u5ef6\u8fdf\uff09\uff1a\u63a5\u6536\u4efb\u4f55\u54cd\u5e94\u6240\u9700\u7684\u6700\u77ed\u65f6\u95f4\u3002\u4f8b\u5982\uff0c\u5047\u8bbe\u6211\u4eec\u901a\u8fc7 Remote Desktop \u8fde\u63a5\u5230\u53e6\u4e00\u4e2a\u7cfb\u7edf\u3002\u9002\u5f53\u7684\u8bf7\u6c42\u548c\u54cd\u5e94\u901a\u8fc7\u7f51\u7edc\u5230\u8fbe\u6211\u4eec\u6240\u9700\u7684\u65f6\u95f4\u5c06\u6307\u793a\u5ef6\u8fdf\u7387\u3002<\/p>\n<\/li>\n<li>\n<p>Throughput: It specifies the amount of work that can be done in a certain period. For example, when copying a file, the throughput can be set based on the number of bytes copied per second. Metrics such as the number of transactions per second or TPS can also be used for enterprise applications.<br \/>\n\u541e\u5410\u91cf\uff1a\u6307\u5b9a\u5728\u4e00\u5b9a\u65f6\u95f4\u5185\u53ef\u4ee5\u5b8c\u6210\u7684\u5de5\u4f5c\u91cf\u3002\u4f8b\u5982\uff0c\u5728\u590d\u5236\u6587\u4ef6\u65f6\uff0c\u53ef\u4ee5\u6839\u636e\u6bcf\u79d2\u590d\u5236\u7684\u5b57\u8282\u6570\u8bbe\u7f6e\u541e\u5410\u91cf\u3002\u6bcf\u79d2\u4e8b\u52a1\u6570\u6216 TPS \u7b49\u6307\u6807\u4e5f\u53ef\u7528\u4e8e\u4f01\u4e1a\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<\/li>\n<li>\n<p>Load: Specifies the amount of pressure on the system. For example, the number of online users can indicate Load. The load is often an important factor in setting up other factors. For example, the response time for ten users may be 1 second, and for 20 users, it may be 5 seconds.<br \/>\n\u8d1f\u8f7d\uff1a\u6307\u5b9a\u7cfb\u7edf\u4e0a\u7684\u538b\u529b\u5927\u5c0f\u3002\u4f8b\u5982\uff0c\u5728\u7ebf\u7528\u6237\u6570\u53ef\u4ee5\u6307\u793a Load \uff08\u8d1f\u8f7d\uff09\u3002\u8d1f\u8f7d\u901a\u5e38\u662f\u8bbe\u7f6e\u5176\u4ed6\u56e0\u7d20\u7684\u91cd\u8981\u56e0\u7d20\u3002\u4f8b\u5982\uff0c10 \u4e2a\u7528\u6237\u7684\u54cd\u5e94\u65f6\u95f4\u53ef\u80fd\u662f 1 \u79d2\uff0c\u800c 20 \u4e2a\u7528\u6237\u7684\u54cd\u5e94\u65f6\u95f4\u53ef\u80fd\u662f 5 \u79d2\u3002<\/p>\n<\/li>\n<li>\n<ul>\n<li>Load sensitivity: A proposition through which the change of response time based on load is specified. For example, assume that system A has a response time of 1 second for several 10-20 users. System B also has a response time of 0.5 seconds for ten users, while if the number of users becomes 20, its response time increases to 2 seconds. In this case, A has less load sensitivity than B.<br \/>\n\u8d1f\u8f7d\u654f\u611f\u5ea6\uff1a\u4e00\u4e2a\u547d\u9898\uff0c\u901a\u8fc7\u8be5\u547d\u9898\u6307\u5b9a\u57fa\u4e8e\u8d1f\u8f7d\u7684\u54cd\u5e94\u65f6\u95f4\u53d8\u5316\u3002\u4f8b\u5982\uff0c\u5047\u8bbe\u7cfb\u7edf A \u5bf9\u51e0\u4e2a 10-20 \u4e2a\u7528\u6237\u7684\u54cd\u5e94\u65f6\u95f4\u4e3a 1 \u79d2\u3002\u7cfb\u7edf B \u5bf9 10 \u4e2a\u7528\u6237\u7684\u54cd\u5e94\u65f6\u95f4\u4e5f\u662f 0.5 \u79d2\uff0c\u800c\u5982\u679c\u7528\u6237\u6570\u91cf\u53d8\u4e3a 20 \u4e2a\uff0c\u5219\u5176\u54cd\u5e94\u65f6\u95f4\u5c06\u589e\u52a0\u5230 2 \u79d2\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0cA \u7684\u8d1f\u8f7d\u654f\u611f\u5ea6\u4f4e\u4e8e B\u3002<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>Efficiency: Performance divided by resources. A system with a TPS volume equal to 40 on 2 CPU cores has better efficiency than a system that brings a TPS volume equal to 50 with 6 CPU cores.<br \/>\n\u6548\u7387\uff1a\u6027\u80fd\u9664\u4ee5\u8d44\u6e90\u3002\u5728 2 \u4e2a CPU \u5185\u6838\u4e0a TPS \u5377\u7b49\u4e8e 40 \u7684\u7cfb\u7edf\u6bd4\u5728 6 \u4e2a CPU \u5185\u6838\u4e0a\u5c06 TPS \u5377\u7b49\u4e8e 50 \u7684\u7cfb\u7edf\u6548\u7387\u66f4\u9ad8\u3002<\/p>\n<\/li>\n<li>\n<p>Capacity of system: A measure that shows the maximum operating power or the maximum effective load that can be tolerated.<br \/>\n\u7cfb\u7edf\u5bb9\u91cf\uff1a\u663e\u793a\u53ef\u4ee5\u627f\u53d7\u7684\u6700\u5927\u8fd0\u884c\u529f\u7387\u6216\u6700\u5927\u6709\u6548\u8d1f\u8f7d\u7684\u5ea6\u91cf\u3002<\/p>\n<\/li>\n<li>\n<p>Scalability: A measure that shows how efficiency is affected by increasing resources. Often, two vertical (Scale Up) and horizontal (Scale Out) methods are used for scalability.<br \/>\n\u53ef\u6269\u5c55\u6027\uff1a\u663e\u793a\u589e\u52a0\u8d44\u6e90\u5982\u4f55\u5f71\u54cd\u6548\u7387\u7684\u5ea6\u91cf\u3002\u901a\u5e38\uff0c\u4f7f\u7528\u4e24\u79cd\u5782\u76f4 \uff08\u7eb5\u5411\u6269\u5c55\uff09 \u548c\u6c34\u5e73 \uff08\u6a2a\u5411\u6269\u5c55\uff09 \u65b9\u6cd5\u6765\u5b9e\u73b0\u53ef\u6269\u5c55\u6027\u3002<\/p>\n<\/li>\n<\/ul>\n<p>The critical point is that design decisions will not necessarily have similar effects on different efficiency factors. Usually, when producing enterprise applications, an effort is made to give higher priority to scalability. Because it can have a more significant effect on efficiency and will be easier to implement. In some situations, a team may prefer to increase the volume rate by implementing a series of complex tasks so they do not have to bear the high costs of purchasing hardware.<\/p>\n<p>\u5173\u952e\u662f\uff0c\u8bbe\u8ba1\u51b3\u7b56\u4e0d\u4e00\u5b9a\u4f1a\u5bf9\u4e0d\u540c\u7684\u6548\u7387\u56e0\u7d20\u4ea7\u751f\u7c7b\u4f3c\u7684\u5f71\u54cd\u3002\u901a\u5e38\uff0c\u5728\u751f\u6210\u4f01\u4e1a\u5e94\u7528\u7a0b\u5e8f\u65f6\uff0c\u4f1a\u52aa\u529b\u63d0\u9ad8\u53ef\u4f38\u7f29\u6027\u7684\u4f18\u5148\u7ea7\u3002\u56e0\u4e3a\u5b83\u53ef\u4ee5\u5bf9\u6548\u7387\u4ea7\u751f\u66f4\u663e\u7740\u7684\u5f71\u54cd\uff0c\u5e76\u4e14\u66f4\u5bb9\u6613\u5b9e\u65bd\u3002\u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\uff0c\u56e2\u961f\u53ef\u80fd\u66f4\u613f\u610f\u901a\u8fc7\u5b9e\u65bd\u4e00\u7cfb\u5217\u590d\u6742\u7684\u4efb\u52a1\u6765\u63d0\u9ad8\u5377\u7387\uff0c\u8fd9\u6837\u4ed6\u4eec\u5c31\u4e0d\u5fc5\u627f\u62c5\u8d2d\u4e70\u786c\u4ef6\u7684\u9ad8\u6210\u672c\u3002<\/p>\n<p>The PofEAA presented in this book is inspired by the patterns presented in the Patterns of Enterprise Applications Architecture book written by Martin Fowler. The following structure is used in presenting PofEAA patterns:<\/p>\n<p>\u672c\u4e66\u4e2d\u4ecb\u7ecd\u7684 PofEAA \u53d7\u5230 Martin Fowler \u64b0\u5199\u7684 Patterns of Enterprise Applications Architecture \u4e00\u4e66\u4e2d\u4ecb\u7ecd\u7684\u6a21\u5f0f\u7684\u542f\u53d1\u3002\u4ee5\u4e0b\u7ed3\u6784\u7528\u4e8e\u5448\u73b0 PofEAA \u6a21\u5f0f\uff1a<\/p>\n<ul>\n<li>\n<p>Name and Classification: It shows the design pattern's name and specifies each design pattern's category.<br \/>\nName and Classification\uff1a\u5b83\u663e\u793a\u8bbe\u8ba1\u6a21\u5f0f\u7684\u540d\u79f0\u5e76\u6307\u5b9a\u6bcf\u4e2a\u8bbe\u8ba1\u6a21\u5f0f\u7684\u7c7b\u522b\u3002<\/p>\n<\/li>\n<li>\n<p>Also Known As: If the design pattern is known by other names, they are introduced in this section.<br \/>\n\u4e5f\u79f0\u4e3a\uff1a\u5982\u679c\u8bbe\u8ba1\u6a21\u5f0f\u6709\u5176\u4ed6\u540d\u79f0\uff0c\u5219\u672c\u8282\u5c06\u4ecb\u7ecd\u5b83\u4eec\u3002<\/p>\n<\/li>\n<li>\n<p>Intent: In this section, brief explanations about the design pattern are given.<br \/>\n\u610f\u56fe\uff1a\u672c\u8282\u7b80\u8981\u4ecb\u7ecd\u4e86\u8bbe\u8ba1\u6a21\u5f0f\u3002<\/p>\n<\/li>\n<li>\n<p>Motivation, Structure, Implementation, and Sample Code: A description of the problem, main structure, implementation steps, and the source code of design patterns are presented.<br \/>\n\u52a8\u673a\u3001\u7ed3\u6784\u3001\u5b9e\u73b0\u548c\u793a\u4f8b\u4ee3\u7801\uff1a\u63d0\u4f9b\u4e86\u95ee\u9898\u63cf\u8ff0\u3001\u4e3b\u8981\u7ed3\u6784\u3001\u5b9e\u73b0\u6b65\u9aa4\u548c\u8bbe\u8ba1\u6a21\u5f0f\u7684\u6e90\u4ee3\u7801\u3002<\/p>\n<\/li>\n<li>\n<p>Notes: Regarding the design and implementation of each design pattern, significant points are given in this section.<br \/>\n\u6ce8\u610f\uff1a\u5173\u4e8e\u6bcf\u79cd\u8bbe\u8ba1\u6a21\u5f0f\u7684\u8bbe\u8ba1\u548c\u5b9e\u73b0\uff0c\u672c\u8282\u4e2d\u7ed9\u51fa\u4e86\u91cd\u8981\u7684\u8981\u70b9\u3002<\/p>\n<\/li>\n<li>\n<p>Consequences: Advantages and disadvantages of the discussed design pattern are given.<br \/>\n\u7ed3\u679c\uff1a\u7ed9\u51fa\u4e86\u6240\u8ba8\u8bba\u7684\u8bbe\u8ba1\u6a21\u5f0f\u7684\u4f18\u7f3a\u70b9\u3002<\/p>\n<\/li>\n<li>\n<p>Applicability: Places, where the discussed design pattern can be helpful, are briefly stated.<br \/>\n\u9002\u7528\u6027\uff1a\u7b80\u8981\u8bf4\u660e\u6240\u8ba8\u8bba\u7684\u8bbe\u8ba1\u6a21\u5f0f\u53ef\u80fd\u6709\u7528\u7684\u4f4d\u7f6e\u3002<\/p>\n<\/li>\n<li>\n<p>Related Patterns: The relationship of each design pattern with other design patterns is mentioned.<br \/>\n\u76f8\u5173\u6a21\u5f0f\uff1a\u63d0\u5230\u4e86\u6bcf\u79cd\u8bbe\u8ba1\u6a21\u5f0f\u4e0e\u5176\u4ed6\u8bbe\u8ba1\u6a21\u5f0f\u7684\u5173\u7cfb\u3002<\/p>\n<\/li>\n<\/ul>\n<h2>Design patterns and software design problems<\/h2>\n<h2>\u8bbe\u8ba1\u6a21\u5f0f\u548c\u8f6f\u4ef6\u8bbe\u8ba1\u95ee\u9898<\/h2>\n<p>When we talk about software design, we are talking about the plan, map, or structural layout on which the software is supposed to be placed. During a software production process, various design problems need to be identified and resolved. This behavior exists in the surrounding world and in real life. For example, when we try to present a solution, it is in line with a specific problem. The same point of view is also valid in the software production process. As mentioned earlier, in a software production process, design patterns solve many different problems. In order to identify and apply a suitable design pattern and a working method for a problem, it is necessary to determine the relationship between the design patterns and the upcoming software problem in the first step. In order to better understand this relationship, you can pay attention to the following:<\/p>\n<p>\u5f53\u6211\u4eec\u8c08\u8bba\u8f6f\u4ef6\u8bbe\u8ba1\u65f6\uff0c\u6211\u4eec\u8c08\u8bba\u7684\u662f\u5e94\u8be5\u653e\u7f6e\u8f6f\u4ef6\u7684\u8ba1\u5212\u3001\u5730\u56fe\u6216\u7ed3\u6784\u5e03\u5c40\u3002\u5728\u8f6f\u4ef6\u751f\u4ea7\u8fc7\u7a0b\u4e2d\uff0c\u9700\u8981\u8bc6\u522b\u548c\u89e3\u51b3\u5404\u79cd\u8bbe\u8ba1\u95ee\u9898\u3002\u8fd9\u79cd\u884c\u4e3a\u5b58\u5728\u4e8e\u5468\u56f4\u7684\u4e16\u754c\u548c\u73b0\u5b9e\u751f\u6d3b\u4e2d\u3002\u4f8b\u5982\uff0c\u5f53\u6211\u4eec\u5c1d\u8bd5\u63d0\u51fa\u89e3\u51b3\u65b9\u6848\u65f6\uff0c\u5b83\u4e0e\u7279\u5b9a\u95ee\u9898\u4e00\u81f4\u3002\u540c\u6837\u7684\u89c2\u70b9\u4e5f\u9002\u7528\u4e8e\u8f6f\u4ef6\u751f\u4ea7\u8fc7\u7a0b\u3002\u5982\u524d\u6240\u8ff0\uff0c\u5728\u8f6f\u4ef6\u751f\u4ea7\u8fc7\u7a0b\u4e2d\uff0c\u8bbe\u8ba1\u6a21\u5f0f\u89e3\u51b3\u4e86\u8bb8\u591a\u4e0d\u540c\u7684\u95ee\u9898\u3002\u4e3a\u4e86\u8bc6\u522b\u5e76\u5e94\u7528\u9002\u5408\u95ee\u9898\u7684\u8bbe\u8ba1\u6a21\u5f0f\u548c\u5de5\u4f5c\u65b9\u6cd5\uff0c\u6709\u5fc5\u8981\u5728\u7b2c\u4e00\u6b65\u4e2d\u786e\u5b9a\u8bbe\u8ba1\u6a21\u5f0f\u4e0e\u5373\u5c06\u5230\u6765\u7684\u8f6f\u4ef6\u95ee\u9898\u4e4b\u95f4\u7684\u5173\u7cfb\u3002\u4e3a\u4e86\u66f4\u597d\u5730\u7406\u89e3\u8fd9\u79cd\u5173\u7cfb\uff0c\u60a8\u53ef\u4ee5\u6ce8\u610f\u4ee5\u4e0b\u51e0\u70b9\uff1a<\/p>\n<p>1.<br \/>\nFinding the right objects: In the world of object-oriented programming, there are many different objects. Each contains a set of data and performs certain tasks. The things that the object can do are called the behavior of the object or its methods. In order to change the content of the data that the object carries, it is necessary to act through methods. One of the most important and most difficult parts of designing and implementing an object-oriented program is decomposing a system into a set of objects. This is difficult because this analysis requires the boundaries of encapsulation, granularity, dependence, flexibility, efficiency, and so on.<br \/>\n\u67e5\u627e\u6b63\u786e\u7684\u5bf9\u8c61\uff1a\u5728\u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\u7684\u4e16\u754c\u4e2d\uff0c\u6709\u8bb8\u591a\u4e0d\u540c\u7684\u5bf9\u8c61\u3002\u6bcf\u4e2a VPN \u90fd\u5305\u542b\u4e00\u7ec4\u6570\u636e\u5e76\u6267\u884c\u67d0\u4e9b\u4efb\u52a1\u3002\u5bf9\u8c61\u53ef\u4ee5\u6267\u884c\u7684\u4f5c\u79f0\u4e3a\u5bf9\u8c61\u7684\u884c\u4e3a\u6216\u5176\u65b9\u6cd5\u3002\u4e3a\u4e86\u66f4\u6539\u5bf9\u8c61\u643a\u5e26\u7684\u6570\u636e\u5185\u5bb9\uff0c\u5fc5\u987b\u901a\u8fc7\u65b9\u6cd5\u8fdb\u884c\u4f5c\u3002\u8bbe\u8ba1\u548c\u5b9e\u73b0\u9762\u5411\u5bf9\u8c61\u7684\u7a0b\u5e8f\u6700\u91cd\u8981\u548c\u6700\u56f0\u96be\u7684\u90e8\u5206\u4e4b\u4e00\u662f\u5c06\u7cfb\u7edf\u5206\u89e3\u4e3a\u4e00\u7ec4\u5bf9\u8c61\u3002\u8fd9\u5f88\u56f0\u96be\uff0c\u56e0\u4e3a\u8fd9\u79cd\u5206\u6790\u9700\u8981\u5c01\u88c5\u3001\u7c92\u5ea6\u3001\u4f9d\u8d56\u6027\u3001\u7075\u6d3b\u6027\u3001\u6548\u7387\u7b49\u754c\u9650\u3002<br \/>\nWhen a problem arises, there are different ways to transform the problem into an object-oriented design. One of the ways is to pay attention to the structure of the sentences, convert the nouns into classes, and present the verbs in the form of methods. For example, in the phrase:<br \/>\n\u5f53\u51fa\u73b0\u95ee\u9898\u65f6\uff0c\u6709\u591a\u79cd\u65b9\u6cd5\u53ef\u4ee5\u5c06\u95ee\u9898\u8f6c\u6362\u4e3a\u9762\u5411\u5bf9\u8c61\u7684\u8bbe\u8ba1\u3002\u5176\u4e2d\u4e00\u79cd\u65b9\u6cd5\u662f\u6ce8\u610f\u53e5\u5b50\u7684\u7ed3\u6784\uff0c\u5c06\u540d\u8bcd\u8f6c\u6362\u4e3a\u7c7b\uff0c\u5e76\u4ee5\u65b9\u6cd5\u7684\u5f62\u5f0f\u5448\u73b0\u52a8\u8bcd\u3002\u4f8b\u5982\uff0c\u5728\u77ed\u8bed\u4e2d\uff1a<br \/>\n&quot;A user can log in to the system by entering the username and password.&quot;<br \/>\n\u201c\u7528\u6237\u53ef\u4ee5\u901a\u8fc7\u8f93\u5165\u7528\u6237\u540d\u548c\u5bc6\u7801\u6765\u767b\u5f55\u7cfb\u7edf\u3002\u201d<br \/>\n&quot;User&quot; has the role of the noun in the sentence, and &quot;login&quot; is the verb of the sentence. Therefore, you can create a class called User, which has a method called Login as the following output:<br \/>\n\u201cUser\u201d \u5728\u53e5\u5b50\u4e2d\u5177\u6709\u540d\u8bcd\u7684\u89d2\u8272\uff0c\u201clogin\u201d \u662f\u53e5\u5b50\u7684\u52a8\u8bcd\u3002\u56e0\u6b64\uff0c\u60a8\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a User \u7684\u7c7b\uff0c\u8be5\u7c7b\u5177\u6709\u4e00\u4e2a\u540d\u4e3a Login \u7684\u65b9\u6cd5\uff0c\u8f93\u51fa\u5982\u4e0b\uff1a<\/p>\n<pre><code>public class User {\n  public void Login(\/*Inputs*\/) {}\n}<\/code><\/pre>\n<p>Another way is to pay attention to the connections, tasks, and interactions and thereby identify the classes, methods, and so on. No matter what method is used, at the end of the design, we may encounter classes for which we need help finding an equivalent in the real world or business environment. Design patterns help in abstractions, and classes can be placed in their proper place and used. For example, the class used to implement the sorting algorithm may not be identified in the early stages of analysis and design, but different design patterns can be designed correctly and connected with the rest of the system.<br \/>\n\u53e6\u4e00\u79cd\u65b9\u6cd5\u662f\u5173\u6ce8\u8fde\u63a5\u3001\u4efb\u52a1\u548c\u4ea4\u4e92\uff0c\u4ece\u800c\u8bc6\u522b\u7c7b\u3001\u65b9\u6cd5\u7b49\u3002\u65e0\u8bba\u4f7f\u7528\u54ea\u79cd\u65b9\u6cd5\uff0c\u5728\u8bbe\u8ba1\u7ed3\u675f\u65f6\uff0c\u6211\u4eec\u90fd\u53ef\u80fd\u4f1a\u9047\u5230\u9700\u8981\u5e2e\u52a9\u5728\u73b0\u5b9e\u4e16\u754c\u6216\u4e1a\u52a1\u73af\u5883\u4e2d\u627e\u5230\u7b49\u6548\u9879\u7684\u7c7b\u3002\u8bbe\u8ba1\u6a21\u5f0f\u6709\u52a9\u4e8e\u62bd\u8c61\uff0c\u5e76\u4e14\u53ef\u4ee5\u5c06\u7c7b\u653e\u7f6e\u5728\u9002\u5f53\u7684\u4f4d\u7f6e\u5e76\u4f7f\u7528\u3002\u4f8b\u5982\uff0c\u5728\u5206\u6790\u548c\u8bbe\u8ba1\u7684\u65e9\u671f\u9636\u6bb5\u53ef\u80fd\u65e0\u6cd5\u8bc6\u522b\u7528\u4e8e\u5b9e\u73b0\u6392\u5e8f\u7b97\u6cd5\u7684\u7c7b\uff0c\u4f46\u53ef\u4ee5\u6b63\u786e\u8bbe\u8ba1\u4e0d\u540c\u7684\u8bbe\u8ba1\u6a21\u5f0f\u5e76\u4e0e\u7cfb\u7edf\u7684\u5176\u4f59\u90e8\u5206\u8fde\u63a5\u3002<\/p>\n<p>2.<br \/>\nRecognizing the granularity of objects: An object has a structure and can be accompanied by various details, and the depth of these details can be very high or low. This factor can affect the size and the number of objects. It is an important decision to decide what boundaries and limits the object structure should have. Design patterns can help form these boundaries and limits accurately.<br \/>\n\u8bc6\u522b\u5bf9\u8c61\u7684\u9897\u7c92\u5ea6\uff1a\u4e00\u4e2a\u5bf9\u8c61\u6709\u4e00\u4e2a\u7ed3\u6784\uff0c\u53ef\u4ee5\u4f34\u968f\u7740\u5404\u79cd\u7ec6\u8282\uff0c\u8fd9\u4e9b\u7ec6\u8282\u7684\u6df1\u5ea6\u53ef\u4ee5\u5f88\u9ad8\uff0c\u4e5f\u53ef\u4ee5\u5f88\u4f4e\u3002\u6b64\u56e0\u7d20\u4f1a\u5f71\u54cd\u5bf9\u8c61\u7684\u5927\u5c0f\u548c\u6570\u91cf\u3002\u51b3\u5b9a\u5bf9\u8c61\u7ed3\u6784\u5e94\u5177\u6709\u54ea\u4e9b\u8fb9\u754c\u548c\u9650\u5236\u662f\u4e00\u4e2a\u91cd\u8981\u7684\u51b3\u5b9a\u3002\u8bbe\u8ba1\u6a21\u5f0f\u53ef\u4ee5\u5e2e\u52a9\u51c6\u786e\u5730\u5f62\u6210\u8fd9\u4e9b\u8fb9\u754c\u548c\u9650\u5236\u3002<\/p>\n<p>3.<br \/>\nKnowing the interface of objects: The behavior of an object consists of the name, input parameters, and output type. These three components together form the signature of a behavior. The set of signatures provided by an object is called a connection or interface of the object. The object interface specifies under what conditions and in what ways a request can be sent to the object. These interfaces are required to communicate with an object, although having information about these does not mean having information about how to implement them. Being able to connect a request to the appropriate object and appropriate behavior at the time of execution is called dynamic binding.<br \/>\n\u4e86\u89e3\u5bf9\u8c61\u7684\u63a5\u53e3\uff1a\u5bf9\u8c61\u7684\u884c\u4e3a\u7531\u540d\u79f0\u3001\u8f93\u5165\u53c2\u6570\u548c\u8f93\u51fa\u7c7b\u578b\u7ec4\u6210\u3002\u8fd9\u4e09\u4e2a\u7ec4\u4ef6\u5171\u540c\u6784\u6210\u4e86\u884c\u4e3a\u7684\u7279\u5f81\u3002\u5bf9\u8c61\u63d0\u4f9b\u7684\u7b7e\u540d\u96c6\u79f0\u4e3a\u5bf9\u8c61\u7684\u8fde\u63a5\u6216\u63a5\u53e3\u3002\u5bf9\u8c61\u63a5\u53e3\u6307\u5b9a\u5728\u4ec0\u4e48\u6761\u4ef6\u4e0b\u4ee5\u53ca\u4ee5\u4ec0\u4e48\u65b9\u5f0f\u53ef\u4ee5\u5411\u5bf9\u8c61\u53d1\u9001\u8bf7\u6c42\u3002\u8fd9\u4e9b\u63a5\u53e3\u662f\u4e0e\u5bf9\u8c61\u901a\u4fe1\u6240\u5fc5\u9700\u7684\uff0c\u5c3d\u7ba1\u62e5\u6709\u6709\u5173\u8fd9\u4e9b\u63a5\u53e3\u7684\u4fe1\u606f\u5e76\u4e0d\u610f\u5473\u7740\u62e5\u6709\u6709\u5173\u5982\u4f55\u5b9e\u73b0\u5b83\u4eec\u7684\u4fe1\u606f\u3002\u80fd\u591f\u5728\u6267\u884c\u65f6\u5c06\u8bf7\u6c42\u8fde\u63a5\u5230\u9002\u5f53\u7684\u5bf9\u8c61\u548c\u9002\u5f53\u7684\u884c\u4e3a\u79f0\u4e3a\u52a8\u6001\u7ed1\u5b9a\u3002<\/p>\n<pre><code>public class Sample {\n  public int GetAge(string name){}\n  public int GetAge(string nationalNo, string name){}\n}<\/code><\/pre>\n<p>Mentioning a request at the time of coding does not mean connecting the request for implementation. This connection will happen at the time of execution, which expresses its dynamic binding. This provides the ability to replace objects with each other at runtime. This is called polymorphism in object orientation. Design patterns also help in shaping such communications and interactions. This design pattern assistance may happen, for example, by placing a constraint on the structure of classes.<br \/>\n\u5728\u7f16\u7801\u65f6\u63d0\u53ca\u8bf7\u6c42\u5e76\u4e0d\u610f\u5473\u7740\u8fde\u63a5 request \u4ee5\u8fdb\u884c\u5b9e\u73b0\u3002\u8fd9\u4e2a\u8fde\u63a5\u5c06\u5728\u6267\u884c\u65f6\u53d1\u751f\uff0c\u8fd9\u8868\u793a\u5b83\u7684\u52a8\u6001\u7ed1\u5b9a\u3002\u8fd9\u63d0\u4f9b\u4e86\u5728\u8fd0\u884c\u65f6\u5c06\u5bf9\u8c61\u76f8\u4e92\u66ff\u6362\u7684\u529f\u80fd\u3002\u8fd9\u5728\u9762\u5411\u5bf9\u8c61\u4e2d\u79f0\u4e3a\u591a\u6001\u6027\u3002\u8bbe\u8ba1\u6a21\u5f0f\u8fd8\u6709\u52a9\u4e8e\u5851\u9020\u6b64\u7c7b\u901a\u4fe1\u548c\u4ea4\u4e92\u3002\u4f8b\u5982\uff0c\u901a\u8fc7\u5bf9\u7c7b\u7684\u7ed3\u6784\u65bd\u52a0\u7ea6\u675f\uff0c\u53ef\u4ee5\u5b9e\u73b0\u8fd9\u79cd\u8bbe\u8ba1\u6a21\u5f0f\u5e2e\u52a9\u3002<\/p>\n<p>4.<br \/>\nKnowing how to implement objects: Objects are created by instantiating from a class which leads to the allocation of memory to the internal data of the object. New classes can also be created as a subset or child of a class using inheritance. In this case, the child class will contain all the accessible data and behaviors of its parent class. If the definition of a class is necessary to leave the implementation of behavior to the children (abstract behavior), then the class can be defined as an abstract class. Since this class is only an abstraction, it cannot be instantiated. If a class is not abstract, then it is called a real or intrinsic class.<br \/>\n\u77e5\u9053\u5982\u4f55\u5b9e\u73b0\u5bf9\u8c61\uff1a\u5bf9\u8c61\u662f\u901a\u8fc7\u4ece\u7c7b\u5b9e\u4f8b\u5316\u6765\u521b\u5efa\u7684\uff0c\u8fd9\u4f1a\u5bfc\u81f4\u5c06\u5185\u5b58\u5206\u914d\u7ed9\u5bf9\u8c61\u7684\u5185\u90e8\u6570\u636e\u3002\u8fd8\u53ef\u4ee5\u4f7f\u7528\u7ee7\u627f\u5c06\u65b0\u7c7b\u521b\u5efa\u4e3a\u7c7b\u7684\u5b50\u96c6\u6216\u5b50\u7c7b\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u5b50\u7c7b\u5c06\u5305\u542b\u5176\u7236\u7c7b\u7684\u6240\u6709\u53ef\u8bbf\u95ee\u6570\u636e\u548c\u884c\u4e3a\u3002\u5982\u679c\u7c7b\u7684\u5b9a\u4e49\u662f\u5fc5\u8981\u7684\uff0c\u4ee5\u4fbf\u5c06\u884c\u4e3a\u7684\u5b9e\u73b0\u7559\u7ed9\u5b50\u7c7b\uff08\u62bd\u8c61\u884c\u4e3a\uff09\uff0c\u5219\u53ef\u4ee5\u5c06\u8be5\u7c7b\u5b9a\u4e49\u4e3a\u62bd\u8c61\u7c7b\u3002\u7531\u4e8e\u6b64\u7c7b\u53ea\u662f\u4e00\u4e2a\u62bd\u8c61\uff0c\u56e0\u6b64\u65e0\u6cd5\u5b9e\u4f8b\u5316\u3002\u5982\u679c\u4e00\u4e2a\u7c7b\u4e0d\u662f\u62bd\u8c61\u7684\uff0c\u90a3\u4e48\u5b83\u88ab\u79f0\u4e3a\u5b9e\u7c7b\u6216\u5185\u90e8\u7c7b\u3002<\/p>\n<pre><code>public abstract class Sample {}\/\/ Abstract class \u62bd\u8c61\u7c7b\npublic class Sample {}\/\/ Intrinsic class \u5185\u90e8\u7c7b\npublic abstract class Sample {\n  public abstract void Get() ;\/\/Abstract method \u62bd\u8c61\u65b9\u6cd5\n}<\/code><\/pre>\n<p>How the objects are instantiated, and classes are formed and implemented are very important points that should be paid attention to. Several design patterns are useful in these situations. For example, one design pattern may help to create static implementations for classes, and another design pattern may help define static structure.<br \/>\n\u5982\u4f55\u5b9e\u4f8b\u5316\u5bf9\u8c61\uff0c\u5982\u4f55\u5f62\u6210\u548c\u5b9e\u73b0\u7c7b\u662f\u5e94\u8be5\u6ce8\u610f\u7684\u975e\u5e38\u91cd\u8981\u7684\u70b9\u3002\u5728\u8fd9\u4e9b\u60c5\u51b5\u4e0b\uff0c\u6709\u51e0\u79cd\u8bbe\u8ba1\u6a21\u5f0f\u5f88\u6709\u7528\u3002\u4f8b\u5982\uff0c\u4e00\u79cd\u8bbe\u8ba1\u6a21\u5f0f\u53ef\u80fd\u6709\u52a9\u4e8e\u4e3a\u7c7b\u521b\u5efa\u9759\u6001\u5b9e\u73b0\uff0c\u800c\u53e6\u4e00\u79cd\u8bbe\u8ba1\u6a21\u5f0f\u53ef\u80fd\u6709\u52a9\u4e8e\u5b9a\u4e49\u9759\u6001\u7ed3\u6784\u3002<\/p>\n<p>5.<br \/>\nDevelopment based on interfaces: With the help of inheritance, a class can access the accessible behavior and data of the parent class and reuse them. Being able to reuse an implementation and having a group of objects with a similar structure are two different stories, which is very important and shows its importance in polymorphism. This usually happens with the help of abstract classes or interfaces.<br \/>\n\u57fa\u4e8e\u63a5\u53e3\u7684\u5f00\u53d1\uff1a\u5728\u7ee7\u627f\u7684\u5e2e\u52a9\u4e0b\uff0c\u7c7b\u53ef\u4ee5\u8bbf\u95ee\u7236\u7c7b\u7684\u53ef\u8bbf\u95ee\u884c\u4e3a\u548c\u6570\u636e\u5e76\u91cd\u7528\u5b83\u4eec\u3002\u80fd\u591f\u91cd\u7528\u4e00\u4e2a\u5b9e\u73b0\u548c\u62e5\u6709\u4e00\u7ec4\u5177\u6709\u76f8\u4f3c\u7ed3\u6784\u7684\u5bf9\u8c61\u662f\u4e24\u4e2a\u4e0d\u540c\u7684\u6545\u4e8b\uff0c\u8fd9\u975e\u5e38\u91cd\u8981\uff0c\u5e76\u663e\u793a\u4e86\u5b83\u5728\u591a\u6001\u6027\u4e2d\u7684\u91cd\u8981\u6027\u3002\u8fd9\u901a\u5e38\u662f\u5728\u62bd\u8c61\u7c7b\u6216\u63a5\u53e3\u7684\u5e2e\u52a9\u4e0b\u53d1\u751f\u7684\u3002<br \/>\nThe use of abstract classes and interfaces makes the user unaware of the exact type of object used in the class. Because the object adheres to the provided abstraction and interface. Also, users are unaware of the classes that implement these objects and only know the abstraction that created the class. This makes it possible to write code based on interfaces and abstractions.<br \/>\n\u4f7f\u7528\u62bd\u8c61\u7c7b\u548c\u63a5\u53e3\u4f1a\u4f7f\u7528\u6237\u4e0d\u77e5\u9053\u7c7b\u4e2d\u4f7f\u7528\u7684\u5bf9\u8c61\u7684\u786e\u5207\u7c7b\u578b\u3002\u56e0\u4e3a\u5bf9\u8c61\u9075\u5faa\u63d0\u4f9b\u7684\u62bd\u8c61\u548c\u63a5\u53e3\u3002\u6b64\u5916\uff0c\u7528\u6237\u4e0d\u77e5\u9053\u5b9e\u73b0\u8fd9\u4e9b\u5bf9\u8c61\u7684\u7c7b\uff0c\u800c\u53ea\u77e5\u9053\u521b\u5efa\u8be5\u7c7b\u7684\u62bd\u8c61\u3002\u8fd9\u4f7f\u5f97\u57fa\u4e8e\u63a5\u53e3\u548c\u62bd\u8c61\u7f16\u5199\u4ee3\u7801\u6210\u4e3a\u53ef\u80fd\u3002<br \/>\nThe main purpose of creational design patterns is to provide different ways to communicate between interfaces and implementations. This category of design patterns tries to provide this communication in an inconspicuous way at the time of instantiating.<br \/>\n\u521b\u5efa\u6027\u8bbe\u8ba1\u6a21\u5f0f\u7684\u4e3b\u8981\u76ee\u7684\u662f\u63d0\u4f9b\u4e0d\u540c\u7684\u65b9\u5f0f\u6765\u5728\u63a5\u53e3\u548c\u5b9e\u73b0\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\u3002\u6b64\u7c7b\u522b\u7684\u8bbe\u8ba1\u6a21\u5f0f\u5c1d\u8bd5\u5728\u5b9e\u4f8b\u5316\u65f6\u4ee5\u4e0d\u663e\u773c\u7684\u65b9\u5f0f\u63d0\u4f9b\u6b64\u901a\u4fe1\u3002<\/p>\n<p>6.<br \/>\nAttention to reuse: Another important problem in software design and implementation is to benefit from reusability and provide appropriate flexibility to the codes. For example, you should pay attention to the differences between inheritance and composition and use each one in the right place. These two are one of the most widely used methods to provide code reusability. Using inheritance, one class can be implemented based on another class. Reusability, in this case, is formed in the form of a child class definition. This type of reuse is called White Box Reuse:<br \/>\n\u6ce8\u610f\u91cd\u7528\uff1a\u8f6f\u4ef6\u8bbe\u8ba1\u548c\u5b9e\u73b0\u4e2d\u7684\u53e6\u4e00\u4e2a\u91cd\u8981\u95ee\u9898\u662f\u4ece\u53ef\u91cd\u7528\u6027\u4e2d\u53d7\u76ca\uff0c\u5e76\u4e3a\u4ee3\u7801\u63d0\u4f9b\u9002\u5f53\u7684\u7075\u6d3b\u6027\u3002\u4f8b\u5982\uff0c\u60a8\u5e94\u8be5\u6ce8\u610f inheritance \u548c composition \u4e4b\u95f4\u7684\u533a\u522b\uff0c\u5e76\u5728\u6b63\u786e\u7684\u5730\u65b9\u4f7f\u7528\u5b83\u4eec\u3002\u8fd9\u4e24\u79cd\u662f\u63d0\u4f9b\u4ee3\u7801\u53ef\u91cd\u7528\u6027\u7684\u6700\u5e7f\u6cdb\u4f7f\u7528\u7684\u65b9\u6cd5\u4e4b\u4e00\u3002\u4f7f\u7528\u7ee7\u627f\uff0c\u4e00\u4e2a\u7c7b\u53ef\u4ee5\u57fa\u4e8e\u53e6\u4e00\u4e2a\u7c7b\u5b9e\u73b0\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u53ef\u91cd\u7528\u6027\u4ee5\u5b50\u7c7b\u5b9a\u4e49\u7684\u5f62\u5f0f\u5f62\u6210\u3002\u8fd9\u79cd\u7c7b\u578b\u7684\u91cd\u7528\u79f0\u4e3a White Box Reuse\uff1a<\/p>\n<pre><code>public class Parent {\n  public void Show_Parent(){}\n}\n\npublic class Child: Parent { \/\/ Inheritance\n  public void Show_Child(){}\n}<\/code><\/pre>\n<p>On the other hand, Composition provides reusability by installing an object in a class and adding new functionality in that class. This type of reuse is also called Black Box Reuse:<br \/>\n\u53e6\u4e00\u65b9\u9762\uff0cComposition \u901a\u8fc7\u5728\u7c7b\u4e2d\u5b89\u88c5\u5bf9\u8c61\u5e76\u5728\u8be5\u7c7b\u4e2d\u6dfb\u52a0\u65b0\u529f\u80fd\u6765\u63d0\u4f9b\u53ef\u91cd\u7528\u6027\u3002\u8fd9\u79cd\u7c7b\u578b\u7684\u91cd\u7528\u4e5f\u79f0\u4e3a\u9ed1\u76d2\u91cd\u7528\uff1a<\/p>\n<pre><code>public class Engine {\n  public void Get(){}\n}\n\npublic class Car {\n  private Engine _engine;\n  public Car(Enging engine)=&gt;_engine = engine;\/\/Composition\n}<\/code><\/pre>\n<p>Both inheritance and composition structures have advantages and disadvantages that should be considered while using them. However, empirically, most programmers overuse inheritance in order to provide reusability, and this causes problems in code development. Using composition can be very helpful in many scenarios. By using delegation, you can give double power to composition. Today, there are other ways that help to reach a code with suitable reusability. For example, in a language like C#, there is a feature called Generic, which can be very useful in this direction. Generics are also called parametrized types. With all these explanations, a series of design patterns help to provide reusability and flexibility well in the code.<br \/>\n\u7ee7\u627f\u7ed3\u6784\u548c\u7ec4\u5408\u7ed3\u6784\u90fd\u6709\u4f18\u70b9\u548c\u7f3a\u70b9\uff0c\u4f7f\u7528\u5b83\u4eec\u65f6\u5e94\u8003\u8651\u8fd9\u4e9b\u4f18\u70b9\u548c\u7f3a\u70b9\u3002\u4f46\u662f\uff0c\u4ece\u7ecf\u9a8c\u4e0a\u8bb2\uff0c\u5927\u591a\u6570\u7a0b\u5e8f\u5458\u8fc7\u5ea6\u4f7f\u7528\u7ee7\u627f\u4ee5\u63d0\u4f9b\u53ef\u91cd\u7528\u6027\uff0c\u8fd9\u4f1a\u5bfc\u81f4\u4ee3\u7801\u5f00\u53d1\u51fa\u73b0\u95ee\u9898\u3002\u5728\u8bb8\u591a\u60c5\u51b5\u4e0b\uff0c\u4f7f\u7528\u7ec4\u5408\u53ef\u80fd\u975e\u5e38\u6709\u7528\u3002\u901a\u8fc7\u4f7f\u7528\u59d4\u6d3e\uff0c\u60a8\u53ef\u4ee5\u4e3a\u7ec4\u5408\u63d0\u4f9b\u53cc\u500d\u7684\u80fd\u529b\u3002\u4eca\u5929\uff0c\u8fd8\u6709\u5176\u4ed6\u65b9\u6cd5\u53ef\u4ee5\u5e2e\u52a9\u83b7\u5f97\u5177\u6709\u9002\u5f53\u53ef\u91cd\u7528\u6027\u7684\u4ee3\u7801\u3002\u4f8b\u5982\uff0c\u5728\u50cf C# \u8fd9\u6837\u7684\u8bed\u8a00\u4e2d\uff0c\u6709\u4e00\u4e2a\u53eb\u505a Generic \u7684\u529f\u80fd\uff0c\u5b83\u5728\u8fd9\u4e2a\u65b9\u5411\u4e0a\u53ef\u80fd\u975e\u5e38\u6709\u7528\u3002\u6cdb\u578b\u4e5f\u79f0\u4e3a\u53c2\u6570\u5316\u7c7b\u578b\u3002\u901a\u8fc7\u6240\u6709\u8fd9\u4e9b\u89e3\u91ca\uff0c\u4e00\u7cfb\u5217\u8bbe\u8ba1\u6a21\u5f0f\u6709\u52a9\u4e8e\u5728\u4ee3\u7801\u4e2d\u5f88\u597d\u5730\u63d0\u4f9b\u53ef\u91cd\u7528\u6027\u548c\u7075\u6d3b\u6027\u3002<\/p>\n<p>6.<br \/>\nDesign for change: It is a suitable and good design that can predict future changes and is not vulnerable to those changes. If the design cannot make a good prediction of the future, it should be ready to apply extensive changes in the future. One of the functions and advantages of design patterns is that it allows the design to be flexible to future changes.<br \/>\n\u4e3a\u53d8\u5316\u800c\u8bbe\u8ba1\uff1a\u8fd9\u662f\u4e00\u79cd\u5408\u9002\u4e14\u826f\u597d\u7684\u8bbe\u8ba1\uff0c\u53ef\u4ee5\u9884\u6d4b\u672a\u6765\u7684\u53d8\u5316\uff0c\u5e76\u4e14\u4e0d\u4f1a\u53d7\u5230\u8fd9\u4e9b\u53d8\u5316\u7684\u5f71\u54cd\u3002\u5982\u679c\u8bbe\u8ba1\u4e0d\u80fd\u5bf9\u672a\u6765\u505a\u51fa\u826f\u597d\u7684\u9884\u6d4b\uff0c\u5b83\u5e94\u8be5\u51c6\u5907\u597d\u5728\u672a\u6765\u5e94\u7528\u5e7f\u6cdb\u7684\u66f4\u6539\u3002\u8bbe\u8ba1\u6a21\u5f0f\u7684\u529f\u80fd\u548c\u4f18\u70b9\u4e4b\u4e00\u662f\u5b83\u5141\u8bb8\u8bbe\u8ba1\u7075\u6d3b\u5730\u9002\u5e94\u672a\u6765\u7684\u53d8\u5316\u3002<\/p>\n<h2>Effective factors in choosing a design pattern<\/h2>\n<h2>\u9009\u62e9\u8bbe\u8ba1\u6a21\u5f0f\u7684\u6709\u6548\u56e0\u7d20<\/h2>\n<p>When first faced with a list of 23 GoF design patterns, it can be difficult to know which pattern to choose for a particular problem. This difficulty increases when we add the PofEAA design patterns to this list of 23 design patterns. It is enough to make the selection process difficult and confusing. In order to make a suitable choice, it is recommended to consider the following points:<\/p>\n<p>\u5f53\u7b2c\u4e00\u6b21\u9762\u5bf9 23 \u4e2a GoF \u8bbe\u8ba1\u6a21\u5f0f\u7684\u5217\u8868\u65f6\uff0c\u53ef\u80fd\u5f88\u96be\u77e5\u9053\u4e3a\u7279\u5b9a\u95ee\u9898\u9009\u62e9\u54ea\u79cd\u6a21\u5f0f\u3002\u5f53\u6211\u4eec\u5c06 PofEAA \u8bbe\u8ba1\u6a21\u5f0f\u6dfb\u52a0\u5230\u8fd9\u4e2a 23 \u79cd\u8bbe\u8ba1\u6a21\u5f0f\u5217\u8868\u4e2d\u65f6\uff0c\u8fd9\u79cd\u96be\u5ea6\u4f1a\u589e\u52a0\u3002\u8fd9\u8db3\u4ee5\u4f7f\u9009\u62e9\u8fc7\u7a0b\u53d8\u5f97\u56f0\u96be\u548c\u6df7\u4e71\u3002\u4e3a\u4e86\u505a\u51fa\u5408\u9002\u7684\u9009\u62e9\uff0c\u5efa\u8bae\u8003\u8651\u4ee5\u4e0b\u51e0\u70b9\uff1a<\/p>\n<ul>\n<li>\n<p>Understanding the problem space and how the design pattern can solve the problem: The first step in choosing a design pattern is to identify the problem correctly. Once the problem becomes clear, think about how the presence of the design pattern can help the problem.<br \/>\n\u4e86\u89e3\u95ee\u9898\u7a7a\u95f4\u4ee5\u53ca\u8bbe\u8ba1\u6a21\u5f0f\u5982\u4f55\u89e3\u51b3\u95ee\u9898\uff1a\u9009\u62e9\u8bbe\u8ba1\u6a21\u5f0f\u7684\u7b2c\u4e00\u6b65\u662f\u6b63\u786e\u8bc6\u522b\u95ee\u9898\u3002\u4e00\u65e6\u95ee\u9898\u53d8\u5f97\u6e05\u6670\uff0c\u5c31\u60f3\u60f3\u8bbe\u8ba1\u6a21\u5f0f\u7684\u5b58\u5728\u5982\u4f55\u5e2e\u52a9\u89e3\u51b3\u95ee\u9898\u3002<\/p>\n<\/li>\n<li>\n<p>Examining the generalities of design patterns using the purpose and scope: By doing this review, you can understand the degree of compatibility of the problem ahead with the design patterns.<br \/>\n\u4f7f\u7528\u76ee\u7684\u548c\u8303\u56f4\u68c0\u67e5\u8bbe\u8ba1\u6a21\u5f0f\u7684\u901a\u7528\u6027\uff1a\u901a\u8fc7\u8fdb\u884c\u6b64\u5ba1\u67e5\uff0c\u60a8\u53ef\u4ee5\u4e86\u89e3\u95ee\u9898\u4e0e\u8bbe\u8ba1\u6a21\u5f0f\u7684\u517c\u5bb9\u6027\u7a0b\u5ea6\u3002<\/p>\n<\/li>\n<li>\n<p>Examining the interconnections of design patterns: For example, if the Abstract Factory design pattern is to be used by combining Singleton with this pattern, only one instance of Abstract Factory can be created. In order to apply dynamics to it, a Prototype can be used.<br \/>\n\u68c0\u67e5\u8bbe\u8ba1\u6a21\u5f0f\u7684\u4e92\u8fde\uff1a\u4f8b\u5982\uff0c\u5982\u679c\u8981\u901a\u8fc7\u5c06 Singleton \u4e0e\u6b64\u6a21\u5f0f\u7ec4\u5408\u6765\u4f7f\u7528 Abstract Factory \u8bbe\u8ba1\u6a21\u5f0f\uff0c\u5219\u53ea\u80fd\u521b\u5efa\u4e00\u4e2a Abstract Factory \u5b9e\u4f8b\u3002\u4e3a\u4e86\u5bf9\u5176\u5e94\u7528\u52a8\u529b\u5b66\uff0c\u53ef\u4ee5\u4f7f\u7528 Prototype\u3002<\/p>\n<\/li>\n<li>\n<p>Examining the similarities and differences of each design pattern: For example, if the problem ahead is a behavioral problem, you can choose the appropriate behavioral pattern among all the behavioral patterns.<br \/>\n\u68c0\u67e5\u6bcf\u79cd\u8bbe\u8ba1\u6a21\u5f0f\u7684\u76f8\u4f3c\u4e4b\u5904\u548c\u4e0d\u540c\u4e4b\u5904\uff1a\u4f8b\u5982\uff0c\u5982\u679c\u524d\u9762\u7684\u95ee\u9898\u662f\u884c\u4e3a\u95ee\u9898\uff0c\u5219\u53ef\u4ee5\u5728\u6240\u6709\u884c\u4e3a\u6a21\u5f0f\u4e2d\u9009\u62e9\u5408\u9002\u7684\u884c\u4e3a\u6a21\u5f0f\u3002<\/p>\n<\/li>\n<li>\n<p>Knowing the reasons that lead to redesign: In this step, the factors that can cause redesign should be known.<br \/>\n\u4e86\u89e3\u5bfc\u81f4\u91cd\u65b0\u8bbe\u8ba1\u7684\u539f\u56e0\uff1a \u5728\u6b64\u6b65\u9aa4\u4e2d\uff0c\u5e94\u4e86\u89e3\u53ef\u80fd\u5bfc\u81f4\u91cd\u65b0\u8bbe\u8ba1\u7684\u56e0\u7d20\u3002<\/p>\n<\/li>\n<li>\n<p>Knowing the design variables: In this step, you should understand what can be changed in the design.<br \/>\n\u4e86\u89e3\u8bbe\u8ba1\u53d8\u91cf\uff1a\u5728\u6b64\u6b65\u9aa4\u4e2d\uff0c\u60a8\u5e94\u8be5\u4e86\u89e3\u8bbe\u8ba1\u4e2d\u53ef\u4ee5\u66f4\u6539\u7684\u5185\u5bb9\u3002<\/p>\n<\/li>\n<\/ul>\n<p>When the appropriate design pattern is chosen, it should be implemented. In order to use and implement a design pattern, you must first study that pattern completely. In this study, the application cases and consequences of the model should be carefully studied and examined. After understanding the generalities of the pattern, the details should be examined, and these details ensure that we know the elements involved have sufficient information about the interactions between these elements.<\/p>\n<p>\u5f53\u9009\u62e9\u4e86\u9002\u5f53\u7684\u8bbe\u8ba1\u6a21\u5f0f\u65f6\uff0c\u5e94\u8be5\u5b9e\u73b0\u5b83\u3002\u4e3a\u4e86\u4f7f\u7528\u548c\u5b9e\u73b0\u8bbe\u8ba1\u6a21\u5f0f\uff0c\u60a8\u5fc5\u987b\u9996\u5148\u5b8c\u6574\u5730\u7814\u7a76\u8be5\u6a21\u5f0f\u3002\u5728\u672c\u7814\u7a76\u4e2d\uff0c\u5e94\u4ed4\u7ec6\u7814\u7a76\u548c\u68c0\u67e5\u8be5\u6a21\u578b\u7684\u5e94\u7528\u6848\u4f8b\u548c\u540e\u679c\u3002\u5728\u4e86\u89e3\u4e86\u6a21\u5f0f\u7684\u4e00\u822c\u6027\u4e4b\u540e\uff0c\u5e94\u8be5\u68c0\u67e5\u7ec6\u8282\uff0c\u8fd9\u4e9b\u7ec6\u8282\u786e\u4fdd\u6211\u4eec\u77e5\u9053\u6240\u6d89\u53ca\u7684\u5143\u7d20\u6709\u8db3\u591f\u7684\u4fe1\u606f\u6765\u4e86\u89e3\u8fd9\u4e9b\u5143\u7d20\u4e4b\u95f4\u7684\u4ea4\u4e92\u3002<\/p>\n<p>In the next step, the way to implement the design pattern will be examined by the existing code samples. Then, we will select the appropriate names for each of the involved elements, taking into account the problem and the business ahead. The choice of name should be made according to the purpose of each element in the upcoming business. After choosing the name, various classes, interfaces, and relationships are implemented. During the implementation, there may be a need to change the codes in different parts of the system. Choosing appropriate names for methods and their implementation are the next steps that should be considered while implementing a design pattern.<\/p>\n<p>\u5728\u4e0b\u4e00\u6b65\u4e2d\uff0c\u5c06\u901a\u8fc7\u73b0\u6709\u7684\u4ee3\u7801\u793a\u4f8b\u6765\u7814\u7a76\u5b9e\u73b0\u8bbe\u8ba1\u6a21\u5f0f\u7684\u65b9\u6cd5\u3002\u7136\u540e\uff0c\u6211\u4eec\u5c06\u8003\u8651\u5230\u95ee\u9898\u548c\u672a\u6765\u7684\u4e1a\u52a1\uff0c\u4e3a\u6bcf\u4e2a\u6d89\u53ca\u7684\u5143\u7d20\u9009\u62e9\u5408\u9002\u7684\u540d\u79f0\u3002\u540d\u79f0\u7684\u9009\u62e9\u5e94\u6839\u636e\u5373\u5c06\u5230\u6765\u7684\u4e1a\u52a1\u4e2d\u6bcf\u4e2a\u5143\u7d20\u7684\u76ee\u7684\u8fdb\u884c\u3002\u9009\u62e9\u540d\u79f0\u540e\uff0c\u5c06\u5b9e\u73b0\u5404\u79cd\u7c7b\u3001\u63a5\u53e3\u548c\u5173\u7cfb\u3002\u5728\u5b9e\u65bd\u8fc7\u7a0b\u4e2d\uff0c\u53ef\u80fd\u9700\u8981\u66f4\u6539\u7cfb\u7edf\u4e0d\u540c\u90e8\u5206\u7684\u4ee3\u7801\u3002\u4e3a\u65b9\u6cd5\u53ca\u5176\u5b9e\u73b0\u9009\u62e9\u5408\u9002\u7684\u540d\u79f0\u662f\u5b9e\u73b0\u8bbe\u8ba1\u6a21\u5f0f\u65f6\u5e94\u8003\u8651\u7684\u4e0b\u4e00\u6b65\u3002<\/p>\n<p><img decoding=\"async\" src=\"\/net7designpatternsindepth\/0110.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 1.10: Choosing Design Pattern Process<br \/>\n\u56fe 1.10.\u9009\u62e9 Design Pattern Process\uff08\u8bbe\u8ba1\u6a21\u5f0f\u6d41\u7a0b\uff09<\/p>\n<h2>.NET<\/h2>\n<p>In 2002, Microsoft released .NET Framework, a development platform for creating Windows apps. Today .NET Framework is at version 4.8 and remains fully supported by Microsoft. In 2014, Microsoft introduced .NET Core as a cross-platform, open-source successor to .NET Framework. This new implementation of .NET kept the name .NET Core through version 3.1. The next version was named .NET 5. The new versions continue to be released annually, with each version number higher. They include significant new features and often enable new scenarios.<\/p>\n<p>2002 \u5e74\uff0cMicrosoft \u53d1\u5e03\u4e86 .NET Framework\uff0c\u8fd9\u662f\u4e00\u4e2a\u7528\u4e8e\u521b\u5efa Windows \u5e94\u7528\u7a0b\u5e8f\u7684\u5f00\u53d1\u5e73\u53f0\u3002\u76ee\u524d\uff0c.NET Framework \u7684\u7248\u672c\u4e3a 4.8\uff0c\u5e76\u4e14\u4ecd\u7136\u53d7\u5230 Microsoft \u7684\u5b8c\u5168\u652f\u6301\u30022014 \u5e74\uff0cMicrosoft \u63a8\u51fa\u4e86 .NET Core \u4f5c\u4e3a .NET Framework \u7684\u8de8\u5e73\u53f0\u5f00\u6e90\u540e\u7ee7\u4ea7\u54c1\u3002\u6b64 .NET \u7684\u65b0\u5b9e\u73b0\u5728\u7248\u672c 3.1 \u4e4b\u524d\u4e00\u76f4\u4fdd\u7559\u540d\u79f0 .NET Core\u3002\u4e0b\u4e00\u4e2a\u7248\u672c\u88ab\u547d\u540d\u4e3a .NET 5\u3002\u65b0\u7248\u672c\u6bcf\u5e74\u90fd\u4f1a\u7ee7\u7eed\u53d1\u5e03\uff0c\u6bcf\u4e2a\u7248\u672c\u53f7\u90fd\u66f4\u9ad8\u3002\u5b83\u4eec\u5305\u62ec\u91cd\u8981\u7684\u65b0\u529f\u80fd\uff0c\u5e76\u4e14\u901a\u5e38\u652f\u6301\u65b0\u65b9\u6848\u3002<\/p>\n<p>There are multiple variants of .NET, each supporting a different type of app. The reason for multiple variants is part historical and technical.<\/p>\n<p>.NET \u6709\u591a\u79cd\u53d8\u4f53\uff0c\u6bcf\u79cd\u53d8\u4f53\u90fd\u652f\u6301\u4e0d\u540c\u7c7b\u578b\u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u591a\u4e2a\u53d8\u4f53\u7684\u539f\u56e0\u90e8\u5206\u662f\u5386\u53f2\u548c\u6280\u672f\u65b9\u9762\u7684\u3002<\/p>\n<p>.NET implementations (historical order):<br \/>\n.NET \u5b9e\u73b0 \uff08\u5386\u53f2\u987a\u5e8f\uff09\uff1a<\/p>\n<ul>\n<li>\n<p>.NET Framework: It provides access to the broad capabilities of Windows and Windows Server. Also extensively used for Windows-based cloud computing. The original .NET.<br \/>\n.NET Framework\uff1a\u5b83\u63d0\u4f9b\u5bf9 Windows \u548c Windows Server \u7684\u5e7f\u6cdb\u529f\u80fd\u7684\u8bbf\u95ee\u3002\u4e5f\u5e7f\u6cdb\u7528\u4e8e\u57fa\u4e8e Windows \u7684\u4e91\u8ba1\u7b97\u3002\u539f\u59cb .NET.<\/p>\n<\/li>\n<li>\n<p>Mono: A cross-platform implementation of .NET Framework. The original community and open-source .NET used for Android, iOS, and Wasm apps.<br \/>\nMono\uff1a.NET Framework \u7684\u8de8\u5e73\u53f0\u5b9e\u73b0\u3002\u7528\u4e8e Android\u3001iOS \u548c Wasm \u5e94\u7528\u7a0b\u5e8f\u7684\u539f\u59cb\u793e\u533a\u548c\u5f00\u6e90 .NET\u3002<\/p>\n<\/li>\n<li>\n<p>.NET (Core): A cross-platform and open-source implementation of .NET, rethought for the cloud age while remaining significantly compatible with the .NET Framework. Used for Linux, macOS, and Windows apps.<br \/>\n.NET\uff08\u6838\u5fc3\uff09\uff1a.NET \u7684\u8de8\u5e73\u53f0\u5f00\u6e90\u5b9e\u73b0\uff0c\u9488\u5bf9\u4e91\u65f6\u4ee3\u8fdb\u884c\u4e86\u91cd\u65b0\u601d\u8003\uff0c\u540c\u65f6\u4fdd\u6301\u4e0e .NET Framework \u7684\u663e\u8457\u517c\u5bb9\u6027\u3002\u7528\u4e8e Linux\u3001macOS \u548c Windows \u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<\/li>\n<\/ul>\n<p>According to the Microsoft .NET website, it is a free, cross-platform, open-source developer for building many different types of applications. With .NET, you can use multiple languages, editors, and libraries to build for web, mobile, desktop, games, IoT, and more. You can write .NET apps in C#, F#, or Visual Basic. C# is a simple, modern, object-oriented, and type-safe programming language. F# is a programming language that makes it easy to write succinct, robust, and performant code. Visual Basic is an approachable language with a simple syntax for building type-safe, object-oriented apps.<\/p>\n<p>\u6839\u636e Microsoft .NET \u7f51\u7ad9\uff0c\u5b83\u662f\u4e00\u4e2a\u514d\u8d39\u7684\u3001\u8de8\u5e73\u53f0\u7684\u5f00\u6e90\u5f00\u53d1\u4eba\u5458\uff0c\u7528\u4e8e\u6784\u5efa\u8bb8\u591a\u4e0d\u540c\u7c7b\u578b\u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u501f\u52a9 .NET\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528\u591a\u79cd\u8bed\u8a00\u3001\u7f16\u8f91\u5668\u548c\u5e93\u6765\u6784\u5efa Web\u3001\u79fb\u52a8\u3001\u684c\u9762\u3001\u6e38\u620f\u3001IoT \u7b49\u3002\u60a8\u53ef\u4ee5\u4f7f\u7528 C#\u3001F# \u6216 Visual Basic \u7f16\u5199 .NET \u5e94\u7528\u7a0b\u5e8f\u3002C# \u662f\u4e00\u79cd\u7b80\u5355\u3001\u73b0\u4ee3\u3001\u9762\u5411\u5bf9\u8c61\u4e14\u7c7b\u578b\u5b89\u5168\u7684\u7f16\u7a0b\u8bed\u8a00\u3002F# \u662f\u4e00\u79cd\u7f16\u7a0b\u8bed\u8a00\uff0c\u53ef\u4ee5\u8f7b\u677e\u7f16\u5199\u7b80\u6d01\u3001\u53ef\u9760\u4e14\u9ad8\u6027\u80fd\u7684\u4ee3\u7801\u3002Visual Basic \u662f\u4e00\u79cd\u6613\u4e8e\u4f7f\u7528\u7684\u8bed\u8a00\uff0c\u5177\u6709\u7b80\u5355\u7684\u8bed\u6cd5\uff0c\u7528\u4e8e\u6784\u5efa\u7c7b\u578b\u5b89\u5168\u3001\u9762\u5411\u5bf9\u8c61\u7684\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<p>Whether you are working in C#, F#, or Visual Basic, the code will run natively on any compatible operating system. You can build many types of apps with .NET. Some are cross-platform and target a specific set of operating systems and devices.<\/p>\n<p>\u65e0\u8bba\u60a8\u662f\u4f7f\u7528 C#\u3001F# \u8fd8\u662f Visual Basic\uff0c\u4ee3\u7801\u90fd\u53ef\u4ee5\u5728\u4efb\u4f55\u517c\u5bb9\u7684\u4f5c\u7cfb\u7edf\u4e0a\u672c\u5730\u8fd0\u884c\u3002\u60a8\u53ef\u4ee5\u4f7f\u7528 .NET \u6784\u5efa\u591a\u79cd\u7c7b\u578b\u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u6709\u4e9b\u662f\u8de8\u5e73\u53f0\u7684\uff0c\u9762\u5411\u4e00\u7ec4\u7279\u5b9a\u7684\u4f5c\u7cfb\u7edf\u548c\u8bbe\u5907\u3002<\/p>\n<p>.NET provides a standard set of base class libraries and APIs that are common to all .NET applications. Each app model can also expose additional APIs that are specific to the operating systems it runs on and the capabilities it provides. For example, ASP.NET is a cross-platform web framework that provides additional APIs for building web apps that run on Linux or Windows.<\/p>\n<p>.NET \u63d0\u4f9b\u4e86\u4e00\u7ec4\u6807\u51c6\u7684\u57fa\u7c7b\u5e93\u548c API\uff0c\u8fd9\u4e9b\u5e93\u548c API \u662f\u6240\u6709 .NET \u5e94\u7528\u7a0b\u5e8f\u901a\u7528\u7684\u3002\u6bcf\u4e2a\u5e94\u7528\u7a0b\u5e8f\u6a21\u578b\u8fd8\u53ef\u4ee5\u516c\u5f00\u7279\u5b9a\u4e8e\u5176\u8fd0\u884c\u7684\u4f5c\u7cfb\u7edf\u53ca\u5176\u63d0\u4f9b\u7684\u529f\u80fd\u7684\u5176\u4ed6 API\u3002\u4f8b\u5982\uff0cASP.NET \u662f\u4e00\u4e2a\u8de8\u5e73\u53f0\u7684 Web \u6846\u67b6\uff0c\u5b83\u63d0\u4f9b\u5176\u4ed6 API \u6765\u6784\u5efa\u5728 Linux \u6216 Windows \u4e0a\u8fd0\u884c\u7684 Web \u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<p>.NET helps you develop high-quality applications faster. Modern language constructs like generics, Language Integrated Query (LINQ), and asynchronous programming make developers productive. Combined with the extensive class libraries, common APIs, multi-language support, and the powerful tooling provided by the Visual Studio family, it is the most productive platform for developers.<\/p>\n<p>.NET \u53ef\u5e2e\u52a9\u60a8\u66f4\u5feb\u5730\u5f00\u53d1\u9ad8\u8d28\u91cf\u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u6cdb\u578b\u3001\u8bed\u8a00\u96c6\u6210\u67e5\u8be2 \uff08LINQ\uff09 \u548c\u5f02\u6b65\u7f16\u7a0b\u7b49\u73b0\u4ee3\u8bed\u8a00\u7ed3\u6784\u4f7f\u5f00\u53d1\u4eba\u5458\u80fd\u591f\u63d0\u9ad8\u5de5\u4f5c\u6548\u7387\u3002\u7ed3\u5408 Visual Studio \u7cfb\u5217\u63d0\u4f9b\u7684\u5927\u91cf\u7c7b\u5e93\u3001\u901a\u7528 API\u3001\u591a\u8bed\u8a00\u652f\u6301\u548c\u5f3a\u5927\u7684\u5de5\u5177\uff0c\u5b83\u662f\u5f00\u53d1\u4eba\u5458\u6700\u9ad8\u6548\u7684\u5e73\u53f0\u3002<\/p>\n<p>.NET 7, the successor to .NET 6, is Microsoft .NET\u2019s latest version which is built for modern cloud-native apps, mobile clients, edge services, and desktop technologies. Creates mobile experiences using a single codebase without compromising native performance using .NET MAUI.<\/p>\n<p>.NET 7 \u662f .NET 6 \u7684\u7ee7\u4efb\u8005\uff0c\u662f Microsoft \u3002NET \u7684\u6700\u65b0\u7248\u672c\uff0c\u4e13\u4e3a\u73b0\u4ee3\u4e91\u539f\u751f\u5e94\u7528\u7a0b\u5e8f\u3001\u79fb\u52a8\u5ba2\u6237\u7aef\u3001\u8fb9\u7f18\u670d\u52a1\u548c\u684c\u9762\u6280\u672f\u800c\u6784\u5efa\u3002\u4f7f\u7528 .NET MAUI \u4f7f\u7528\u5355\u4e2a\u4ee3\u7801\u5e93\u521b\u5efa\u79fb\u52a8\u4f53\u9a8c\uff0c\u800c\u4e0d\u4f1a\u5f71\u54cd\u672c\u673a\u6027\u80fd\u3002<\/p>\n<p>.NET apps and libraries are built from source code and project files using the .NET CLI or an Integrated Development Environment (IDE) like Visual Studio.<\/p>\n<p>.NET \u5e94\u7528\u7a0b\u5e8f\u548c\u5e93\u662f\u4f7f\u7528 .NET CLI \u6216\u96c6\u6210\u5f00\u53d1\u73af\u5883 \uff08IDE\uff09\uff08\u5982 Visual Studio\uff09\u4ece\u6e90\u4ee3\u7801\u548c\u9879\u76ee\u6587\u4ef6\u6784\u5efa\u7684\u3002<\/p>\n<p>The following example is a minimal .NET app:<br \/>\n\u4ee5\u4e0b\u793a\u4f8b\u662f\u4e00\u4e2a\u6700\u5c0f\u7684 .NET \u5e94\u7528\u7a0b\u5e8f\uff1a<\/p>\n<p>Project file:<br \/>\n\u9879\u76ee\u6587\u4ef6\uff1a<\/p>\n<pre><code>&lt;Project Sdk=&quot;Microsoft.NET.Sdk&quot;&gt;\n  &lt;PropertyGroup&gt;\n    &lt;OutputType&gt;Exe&lt;\/OutputType&gt;\n    &lt;TargetFramework&gt;net7.0&lt;\/TargetFramework&gt;\n  &lt;\/PropertyGroup&gt;\n&lt;\/Project&gt;<\/code><\/pre>\n<p>Source Code:<br \/>\n\u6e90\u4ee3\u7801\uff1a<\/p>\n<pre><code>Console.WriteLine(&quot;Welcome to .NET 7 Design Patterns, in Depth!&quot;);<\/code><\/pre>\n<p>The app can be built and run with the .NET CLI:<br \/>\n\u53ef\u4ee5\u4f7f\u7528 .NET CLI \u6784\u5efa\u548c\u8fd0\u884c\u8be5\u5e94\u7528\u7a0b\u5e8f\uff1a<\/p>\n<pre><code>% dotnet run<\/code><\/pre>\n<p>It can also be built and run as two separate steps. The following example is for an app that is named app:<br \/>\n\u5b83\u8fd8\u53ef\u4ee5\u4f5c\u4e3a\u4e24\u4e2a\u5355\u72ec\u7684\u6b65\u9aa4\u6784\u5efa\u548c\u8fd0\u884c\u3002\u4ee5\u4e0b\u793a\u4f8b\u9002\u7528\u4e8e\u540d\u4e3a app \u7684\u5e94\u7528\u7a0b\u5e8f\uff1a<\/p>\n<pre><code>% dotnet build\n\n% .\/bin\/Debug\/net6.0\/app<\/code><\/pre>\n<p>According to the Microsoft .NET website, new versions are released annually in November. .NET released in odd-numbered years are Long-Term Support (LTS) and are supported for three years. Versions that are released in even-numbered years are Standard-Term Support (STS) and are kept for 18 months. The quality level, breaking change policies, and all other aspects of the releases are the same. The .NET Team at Microsoft works collaboratively with other organizations such as Red Hat (for Red Hat Enterprise Linux) and Samsung (for Tizen Platform) to distribute and support .NET in various ways.<\/p>\n<p>\u6839\u636e Microsoft .NET \u7f51\u7ad9\uff0c\u65b0\u7248\u672c\u6bcf\u5e74 11 \u6708\u53d1\u5e03\u3002\u5947\u6570\u5e74\u53d1\u5e03\u7684 .NET \u662f\u957f\u671f\u652f\u6301 \uff08LTS\uff09\uff0c\u652f\u6301\u671f\u9650\u4e3a\u4e09\u5e74\u3002\u5728\u5076\u6570\u5e74\u53d1\u5e03\u7684\u7248\u672c\u662f\u6807\u51c6\u671f\u9650\u652f\u6301 \uff08STS\uff09\uff0c\u4fdd\u7559 18 \u4e2a\u6708\u3002\u8d28\u91cf\u7ea7\u522b\u3001\u4e2d\u65ad\u6027\u53d8\u66f4\u7b56\u7565\u548c\u7248\u672c\u7684\u6240\u6709\u5176\u4ed6\u65b9\u9762\u90fd\u662f\u76f8\u540c\u7684\u3002Microsoft \u7684 .NET \u56e2\u961f\u4e0e\u5176\u4ed6\u7ec4\u7ec7\u5408\u4f5c\uff0c\u4f8b\u5982 Red Hat\uff08\u7528\u4e8e Red Hat Enterprise Linux\uff09\u548c Samsung\uff08\u7528\u4e8e Tizen \u5e73\u53f0\uff09\uff0c\u4ee5\u5404\u79cd\u65b9\u5f0f\u5206\u53d1\u548c\u652f\u6301 .NET\u3002<\/p>\n<h2>Introduction to object orientation in .NET<\/h2>\n<h2>.NET\u4e2d\u7684\u9762\u5411\u5bf9\u8c61\u7b80\u4ecb<\/h2>\n<p>An object in the real world is a thing. For example, John's car, Paul's mobile, Sara's table, and so on are all objects in the real world. There is a similar view in the programming world where an object is a representation of something in the real world. For example, Tom's bank account in the financial software is the same representative of Tom's bank account in the real world. Dealing with the details of object orientation and object-oriented programming is beyond the scope of this chapter, but in the following, we will get to know some important concepts of object orientation.<\/p>\n<p>\u73b0\u5b9e\u4e16\u754c\u4e2d\u7684\u5bf9\u8c61\u662f\u4e00\u4e2a\u4e8b\u7269\u3002\u4f8b\u5982\uff0cJohn \u7684\u6c7d\u8f66\u3001Paul \u7684\u79fb\u52a8\u8bbe\u5907\u3001Sara \u7684\u684c\u5b50\u7b49\u7b49\u90fd\u662f\u73b0\u5b9e\u4e16\u754c\u4e2d\u7684\u5bf9\u8c61\u3002\u5728\u7f16\u7a0b\u4e16\u754c\u4e2d\u4e5f\u6709\u7c7b\u4f3c\u7684\u89c2\u70b9\uff0c\u5176\u4e2d\u5bf9\u8c61\u662f\u73b0\u5b9e\u4e16\u754c\u4e2d\u67d0\u7269\u7684\u8868\u793a\u3002\u4f8b\u5982\uff0cTom \u5728\u8d22\u52a1\u8f6f\u4ef6\u4e2d\u7684\u94f6\u884c\u8d26\u6237\u4e0e\u73b0\u5b9e\u4e16\u754c\u4e2d Tom \u7684\u94f6\u884c\u8d26\u6237\u662f\u540c\u4e00\u4e2a\u4ee3\u8868\u3002\u5904\u7406\u9762\u5411\u5bf9\u8c61\u548c\u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\u7684\u7ec6\u8282\u8d85\u51fa\u4e86\u672c\u7ae0\u7684\u8303\u56f4\uff0c\u4f46\u5728\u4e0b\u6587\u4e2d\uff0c\u6211\u4eec\u5c06\u4e86\u89e3\u9762\u5411\u5bf9\u8c61\u7684\u4e00\u4e9b\u91cd\u8981\u6982\u5ff5\u3002<\/p>\n<p>In the C# programming language, the class or struct keywords are used to define the type of an object that is actually the outline and format of the object. Object orientation has a series of main and fundamental concepts that are briefly discussed in the following:<\/p>\n<p>\u5728 C# \u7f16\u7a0b\u8bed\u8a00\u4e2d\uff0cclass \u6216 struct \u5173\u952e\u5b57\u7528\u4e8e\u5b9a\u4e49\u5bf9\u8c61\u7684\u7c7b\u578b\uff0c\u8be5\u7c7b\u578b\u5b9e\u9645\u4e0a\u662f\u5bf9\u8c61\u7684\u8f6e\u5ed3\u548c\u683c\u5f0f\u3002\u9762\u5411\u5bf9\u8c61\u5177\u6709\u4e00\u7cfb\u5217\u4e3b\u8981\u548c\u57fa\u672c\u6982\u5ff5\uff0c\u4e0b\u9762\u5c06\u7b80\u8981\u8ba8\u8bba\u8fd9\u4e9b\u6982\u5ff5\uff1a<\/p>\n<p>Encapsulation: Deals directly with the data and methods associated with the object. By using encapsulation, we control access to data and methods and assert how the internal state of an object can be changed.<\/p>\n<p>\u5c01\u88c5\uff1a\u76f4\u63a5\u5904\u7406\u4e0e\u5bf9\u8c61\u5173\u8054\u7684\u6570\u636e\u548c\u65b9\u6cd5\u3002\u901a\u8fc7\u4f7f\u7528\u5c01\u88c5\uff0c\u6211\u4eec\u53ef\u4ee5\u63a7\u5236\u5bf9\u6570\u636e\u548c\u65b9\u6cd5\u7684\u8bbf\u95ee\uff0c\u5e76\u65ad\u8a00\u5982\u4f55\u66f4\u6539\u5bf9\u8c61\u7684\u5185\u90e8\u72b6\u6001\u3002<\/p>\n<pre><code>public class DemoEncap\n{\n  private int studentAge;\n\n  \/\/ You can access the field only by using the following methods.\n  \/\/So, this field is encapsulated &amp; access to it, is controlled\n  public int Age\n  {\n    get =&gt; studentAge;\n    set =&gt; studentAge = value;\n  }\n}<\/code><\/pre>\n<p>Composition: Describes what an object is made of. For example, a car consists of four wheels.<br \/>\n\u6784\u56fe\uff1a\u63cf\u8ff0\u5bf9\u8c61\u7684\u6784\u6210\u3002\u4f8b\u5982\uff0c\u4e00\u8f86\u6c7d\u8f66\u7531\u56db\u4e2a\u8f6e\u5b50\u7ec4\u6210\u3002<\/p>\n<p>Aggregation: States what things can be mixed with the object. For example, a human is not part of a car, but a human can sit inside the car and try to drive.<br \/>\n\u805a\u5408\uff1a\u8bf4\u660e\u54ea\u4e9b\u5185\u5bb9\u53ef\u4ee5\u4e0e\u5bf9\u8c61\u6df7\u5408\u3002\u4f8b\u5982\uff0c\u4eba\u7c7b\u4e0d\u662f\u6c7d\u8f66\u7684\u4e00\u90e8\u5206\uff0c\u4f46\u4eba\u7c7b\u53ef\u4ee5\u5750\u5728\u8f66\u5185\u5e76\u5c1d\u8bd5\u9a7e\u9a76\u3002<\/p>\n<p>Inheritance: By using inheritance, existing codes can be reused. This reuse happens in the form of defining a child class based on the parent class. In this case, all access methods and features of the parent class are available to the child class. Also, with the help of inheritance, you can develop the capabilities of the parent class. When using inheritance, two types of casting can occur.<br \/>\n\u7ee7\u627f\uff1a\u901a\u8fc7\u4f7f\u7528\u7ee7\u627f\uff0c\u53ef\u4ee5\u91cd\u7528\u73b0\u6709\u4ee3\u7801\u3002\u8fd9\u79cd\u91cd\u7528\u4ee5\u57fa\u4e8e\u7236\u7c7b\u5b9a\u4e49\u5b50\u7c7b\u7684\u5f62\u5f0f\u53d1\u751f\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u7236\u7c7b\u7684\u6240\u6709\u8bbf\u95ee\u65b9\u6cd5\u548c\u529f\u80fd\u90fd\u53ef\u4f9b\u5b50\u7c7b\u4f7f\u7528\u3002\u6b64\u5916\uff0c\u5728\u7ee7\u627f\u7684\u5e2e\u52a9\u4e0b\uff0c\u60a8\u53ef\u4ee5\u5f00\u53d1\u7236\u7c7b\u7684\u529f\u80fd\u3002\u4f7f\u7528\u7ee7\u627f\u65f6\uff0c\u53ef\u80fd\u4f1a\u53d1\u751f\u4e24\u79cd\u7c7b\u578b\u7684\u5f3a\u5236\u8f6c\u6362\u3002<\/p>\n<p>Implicit casting: Means to store the child class object in a parent class variable<br \/>\n\u9690\u5f0f\u5f3a\u5236\u8f6c\u6362\uff1a\u8868\u793a\u5c06\u5b50\u7c7b\u5bf9\u8c61\u5b58\u50a8\u5728\u7236\u7c7b\u53d8\u91cf\u4e2d<\/p>\n<p>Explicit casting: In this type of casting, the type of destination should be stated explicitly. In this method, there is a possibility of an exception, so it is better to check whether Casting can be done or not by using the keyword before doing Casting.<br \/>\n\u663e\u5f0f\u5f3a\u5236\u8f6c\u6362\uff1a\u5728\u8fd9\u79cd\u7c7b\u578b\u7684\u5f3a\u5236\u8f6c\u6362\u4e2d\uff0c\u5e94\u663e\u5f0f\u8bf4\u660e\u76ee\u6807\u7684\u7c7b\u578b\u3002\u5728\u8fd9\u79cd\u65b9\u6cd5\u4e2d\uff0c\u6709\u51fa\u73b0\u5f02\u5e38\u7684\u53ef\u80fd\uff0c\u6240\u4ee5\u6700\u597d\u5728\u505a Casting \u4e4b\u524d\uff0c\u5148\u7528\u5173\u952e\u8bcd\u68c0\u67e5\u4e00\u4e0b\u662f\u5426\u53ef\u4ee5\u505a Casting\u3002<\/p>\n<p>Abstraction: By using abstraction, the main idea of the object is identified, and the details are ignored. The child classes have the chance to implement the details based on their own problem space. In C# language, you can use the abstract keyword to define an abstract class or method, which is usually considered as classes that continue to implement the introduced abstractions using the inheritance of child classes. The volume and extent of abstraction of a class are important points that should be taken into account. The more abstract the class, the more we can use it, but there will be less code to share.<br \/>\n\u62bd\u8c61\uff1a\u901a\u8fc7\u4f7f\u7528\u62bd\u8c61\uff0c\u53ef\u4ee5\u8bc6\u522b\u5bf9\u8c61\u7684\u4e3b\u4f53\u601d\u60f3\uff0c\u5ffd\u7565\u7ec6\u8282\u3002\u5b50\u7c7b\u6709\u673a\u4f1a\u6839\u636e\u81ea\u5df1\u7684\u95ee\u9898\u7a7a\u95f4\u5b9e\u73b0\u7ec6\u8282\u3002\u5728 C# \u8bed\u8a00\u4e2d\uff0c\u53ef\u4ee5\u4f7f\u7528 abstract \u5173\u952e\u5b57\u5b9a\u4e49\u62bd\u8c61\u7c7b\u6216\u65b9\u6cd5\uff0c\u8be5\u7c7b\u6216\u65b9\u6cd5\u901a\u5e38\u88ab\u89c6\u4e3a\u4f7f\u7528\u5b50\u7c7b\u7684\u7ee7\u627f\u7ee7\u7eed\u5b9e\u73b0\u5f15\u5165\u7684\u62bd\u8c61\u7684\u7c7b\u3002\u7c7b\u7684\u62bd\u8c61\u91cf\u548c\u8303\u56f4\u662f\u5e94\u8be5\u8003\u8651\u7684\u91cd\u8981\u70b9\u3002\u7c7b\u8d8a\u62bd\u8c61\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u5b83\u5c31\u8d8a\u591a\uff0c\u4f46\u8981\u5171\u4eab\u7684\u4ee3\u7801\u4f1a\u66f4\u5c11\u3002<\/p>\n<p>Polymorphism: By using polymorphism, the child class has the ability to change the implementation of its parent class. In order to change the parent class, the child class can change the implementation of the method using the override keyword in the C# programming language. In order for the implementation of the method to be changeable, the parent class must define the method as virtual. The members that are defined as abstract in the parent class will use the override keyword in the child class for implementation. If a method is defined in the parent class and a method with the same signature is defined in the child class, it is said that the process is hidden (Method Hiding). This type of inheritance is called non-polymorphic inheritance. In order to define this type of method, the new keyword can be used, although the use of this keyword is optional.<br \/>\n\u591a\u6001\u6027\uff1a\u901a\u8fc7\u4f7f\u7528\u591a\u6001\u6027\uff0c\u5b50\u7c7b\u80fd\u591f\u66f4\u6539\u5176\u7236\u7c7b\u7684\u5b9e\u73b0\u3002\u4e3a\u4e86\u66f4\u6539\u7236\u7c7b\uff0c\u5b50\u7c7b\u53ef\u4ee5\u4f7f\u7528 C# \u7f16\u7a0b\u8bed\u8a00\u4e2d\u7684 override \u5173\u952e\u5b57\u66f4\u6539\u65b9\u6cd5\u7684\u5b9e\u73b0\u3002\u4e3a\u4e86\u4f7f\u65b9\u6cd5\u7684\u5b9e\u73b0\u662f\u53ef\u66f4\u6539\u7684\uff0c\u7236\u7c7b\u5fc5\u987b\u5c06\u65b9\u6cd5\u5b9a\u4e49\u4e3a virtual\u3002\u5728\u7236\u7c7b\u4e2d\u5b9a\u4e49\u4e3a abstract \u7684\u6210\u5458\u5c06\u4f7f\u7528\u5b50\u7c7b\u4e2d\u7684 override \u5173\u952e\u5b57\u8fdb\u884c\u5b9e\u73b0\u3002\u5982\u679c\u5728\u7236\u7c7b\u4e2d\u5b9a\u4e49\u4e86\u65b9\u6cd5\uff0c\u5e76\u4e14\u5728\u5b50\u7c7b\u4e2d\u5b9a\u4e49\u4e86\u5177\u6709\u76f8\u540c\u7b7e\u540d\u7684\u65b9\u6cd5\uff0c\u5219\u79f0\u8be5\u8fdb\u7a0b\u662f\u9690\u85cf\u7684\uff08\u65b9\u6cd5\u9690\u85cf\uff09\u3002\u8fd9\u79cd\u7c7b\u578b\u7684\u7ee7\u627f\u79f0\u4e3a\u975e\u591a\u6001\u7ee7\u627f\u3002\u4e3a\u4e86\u5b9a\u4e49\u8fd9\u79cd\u7c7b\u578b\u7684\u65b9\u6cd5\uff0c\u53ef\u4ee5\u4f7f\u7528 new \u5173\u952e\u5b57\uff0c\u5c3d\u7ba1\u6b64\u5173\u952e\u5b57\u7684\u4f7f\u7528\u662f\u53ef\u9009\u7684\u3002<\/p>\n<pre><code>P class A\n{\n  public void Print() =&gt; Console.WriteLine(&quot;I am Parent&quot;);\n}\n\npublic class B: A\n{\n  public new void Print() =&gt; Console.WriteLine(&quot;I am Child&quot;);\n}\n<\/code><\/pre>\n<p>When we are dealing with a large class, the implementation of the class can be written in several formats. In this case, the class is called partial. A class in C# can have different members, including the following:<br \/>\n\u5f53\u6211\u4eec\u5904\u7406\u4e00\u4e2a\u5927\u578b\u7c7b\u65f6\uff0c\u7c7b\u7684\u5b9e\u73b0\u53ef\u4ee5\u7528\u591a\u79cd\u683c\u5f0f\u7f16\u5199\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u8be5\u7c7b\u79f0\u4e3a partial\u3002C# \u4e2d\u7684\u7c7b\u53ef\u4ee5\u5177\u6709\u4e0d\u540c\u7684\u6210\u5458\uff0c\u5305\u62ec\uff1a<\/p>\n<p>Field: The field is used to store data. Fields have three different categories:<br \/>\n\u5b57\u6bb5\uff1a\u8be5\u5b57\u6bb5\u7528\u4e8e\u5b58\u50a8\u6570\u636e\u3002\u5b57\u6bb5\u6709\u4e09\u4e2a\u4e0d\u540c\u7684\u7c7b\u522b\uff1a<br \/>\nConstant: The data that is placed in these types of fields will never change, and the compiler copies the relevant data, where the constants are called.<br \/>\n\u5e38\u91cf\uff1a\u653e\u7f6e\u5728\u8fd9\u4e9b\u7c7b\u578b\u7684\u5b57\u6bb5\u4e2d\u7684\u6570\u636e\u6c38\u8fdc\u4e0d\u4f1a\u66f4\u6539\uff0c\u7f16\u8bd1\u5668\u4f1a\u590d\u5236\u8c03\u7528\u5e38\u91cf\u7684\u76f8\u5173\u6570\u636e\u3002<\/p>\n<p>For example, consider the following code:<br \/>\n\u4f8b\u5982\uff0c\u8bf7\u8003\u8651\u4ee5\u4e0b\u4ee3\u7801\uff1a<\/p>\n<pre><code>public class A\n{\n  public const string SampleConst = &quot;.NET Design Patterns&quot;;\n}\n\npublic class B\n{\n  public B()\n  {\n    string test = A.SampleConst;\n  }\n}<\/code><\/pre>\n<p>After compiling the code, the compiler will generate the following code: (The generated IL code is captured by ILSpy software)<br \/>\n\u7f16\u8bd1\u4ee3\u7801\u540e\uff0c\u7f16\u8bd1\u5668\u4f1a\u751f\u6210\u5982\u4e0b\u4ee3\u7801\uff1a\uff08\u751f\u6210\u7684 IL \u4ee3\u7801\u88ab ILSpy \u8f6f\u4ef6\u6355\u83b7\uff09<\/p>\n<pre><code>public class A\n{\n  public const string SampleConst = &quot;.NET Design Patterns&quot;;\n}\n\npublic class B\n{\n  public B()\n  {\n    string test =&quot;.NET Desig Patterns&quot;;\n  }\n}<\/code><\/pre>\n<p>As you can see, the compiler copies the value of SampleConst wherever the constant is used.<br \/>\n\u5982\u60a8\u6240\u89c1\uff0c\u7f16\u8bd1\u5668\u4f1a\u5728\u4f7f\u7528\u5e38\u91cf\u7684\u4f4d\u7f6e\u590d\u5236 SampleConst \u7684\u503c\u3002<br \/>\nRead Only: The data in these types of fields cannot be changed after creating the object.<br \/>\n\u53ea\u8bfb\uff1a\u521b\u5efa\u5bf9\u8c61\u540e\uff0c\u65e0\u6cd5\u66f4\u6539\u8fd9\u4e9b\u7c7b\u578b\u5b57\u6bb5\u4e2d\u7684\u6570\u636e\u3002<br \/>\nEvent: In these types of fields, the available data is actually a reference to one or more methods that are supposed to be executed when a specific event occurs.<br \/>\n\u4e8b\u4ef6\uff1a\u5728\u8fd9\u4e9b\u7c7b\u578b\u7684\u5b57\u6bb5\u4e2d\uff0c\u53ef\u7528\u6570\u636e\u5b9e\u9645\u4e0a\u662f\u5bf9\u4e00\u4e2a\u6216\u591a\u4e2a\u65b9\u6cd5\u7684\u5f15\u7528\uff0c\u8fd9\u4e9b\u65b9\u6cd5\u5e94\u8be5\u5728\u7279\u5b9a\u4e8b\u4ef6\u53d1\u751f\u65f6\u6267\u884c\u3002<br \/>\nMethod: These are used to execute expressions. The method defines and implements the expected behavior of the object. It has a name, input parameters, and output type. If two methods have the same name but different input parameters, they are said to be overloaded. Methods also have four different types:<br \/>\n\u65b9\u6cd5\uff1a\u8fd9\u4e9b\u7528\u4e8e\u6267\u884c\u8868\u8fbe\u5f0f\u3002\u8be5\u65b9\u6cd5\u5b9a\u4e49\u5e76\u5b9e\u73b0\u5bf9\u8c61\u7684\u9884\u671f\u884c\u4e3a\u3002\u5b83\u5177\u6709\u540d\u79f0\u3001\u8f93\u5165\u53c2\u6570\u548c\u8f93\u51fa\u7c7b\u578b\u3002\u5982\u679c\u4e24\u4e2a\u65b9\u6cd5\u5177\u6709\u76f8\u540c\u7684\u540d\u79f0\u4f46\u4e0d\u540c\u7684\u8f93\u5165\u53c2\u6570\uff0c\u5219\u79f0\u5b83\u4eec\u88ab\u91cd\u8f7d\u3002\u65b9\u6cd5\u4e5f\u6709\u56db\u79cd\u4e0d\u540c\u7684\u7c7b\u578b\uff1a<br \/>\nConstructor: The constructor allocates memory to the object and initializes it. When the new keyword is used in the C# programming language, the associated constructor will be executed.<br \/>\n\u6784\u9020\u51fd\u6570\uff1a\u6784\u9020\u51fd\u6570\u4e3a\u5bf9\u8c61\u5206\u914d\u5185\u5b58\u5e76\u5bf9\u5176\u8fdb\u884c\u521d\u59cb\u5316\u3002\u5728 C# \u7f16\u7a0b\u8bed\u8a00\u4e2d\u4f7f\u7528 new \u5173\u952e\u5b57\u65f6\uff0c\u5c06\u6267\u884c\u5173\u8054\u7684\u6784\u9020\u51fd\u6570\u3002<br \/>\nFinalizer: These methods, also called destructors, are rarely used in the C# language. During execution, when an object is disposing and reclaiming memory, then these types of methods are executed.<br \/>\n\u7ec8\u7ed3\u5668\uff1a\u8fd9\u4e9b\u65b9\u6cd5\u4e5f\u79f0\u4e3a\u6790\u6784\u51fd\u6570\uff0c\u5728 C# \u8bed\u8a00\u4e2d\u5f88\u5c11\u4f7f\u7528\u3002\u5728\u6267\u884c\u671f\u95f4\uff0c\u5f53\u5bf9\u8c61\u91ca\u653e\u548c\u56de\u6536\u5185\u5b58\u65f6\uff0c\u5c06\u6267\u884c\u8fd9\u4e9b\u7c7b\u578b\u7684\u65b9\u6cd5\u3002<\/p>\n<pre><code>class Car\n{\n  ~Car() \/\/ finalizer\n  {\n    \/\/ cleanup statements...\n  }\n}<\/code><\/pre>\n<p>In the preceding code, the Finalizer implicitly calls the Finalize method in the Object class. So, calling Finalizer will result in calling the following manner:<br \/>\n\u5728\u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\uff0cFinalizer \u9690\u5f0f\u8c03\u7528 Object \u7c7b\u4e2d\u7684 Finalize \u65b9\u6cd5\u3002\u56e0\u6b64\uff0c\u8c03\u7528 Finalizer \u5c06\u5bfc\u81f4\u4ee5\u4e0b\u65b9\u5f0f\u8c03\u7528\uff1a<\/p>\n<pre><code>protected override void Finalize()\n  {\n    try\n  {\n    \/\/ Cleanup statements...\n  }\n    finally\n  {\n    base.Finalize();\n  }\n}<\/code><\/pre>\n<p>Property: Statements in this type of method will be executed while setting or reading data. Behind the scenes of property, data is usually stored in Fields. There is no requirement for this purpose, and the data can be stored in an external data source or calculated during execution. Usually, the Property can be used for field encapsulation.<br \/>\nProperty\uff1a\u5728\u8bbe\u7f6e\u6216\u8bfb\u53d6\u6570\u636e\u65f6\uff0c\u5c06\u6267\u884c\u6b64\u7c7b\u65b9\u6cd5\u4e2d\u7684\u8bed\u53e5\u3002\u5728\u5c5e\u6027\u7684\u5e55\u540e\uff0c\u6570\u636e\u901a\u5e38\u5b58\u50a8\u5728 Fields \u4e2d\u3002\u6ca1\u6709\u6b64\u76ee\u7684\u7684\u8981\u6c42\uff0c\u6570\u636e\u53ef\u4ee5\u5b58\u50a8\u5728\u5916\u90e8\u6570\u636e\u6e90\u4e2d\u6216\u5728\u6267\u884c\u671f\u95f4\u8fdb\u884c\u8ba1\u7b97\u3002\u901a\u5e38\uff0cProperty \u53ef\u7528\u4e8e\u5b57\u6bb5\u5c01\u88c5\u3002<\/p>\n<pre><code>  public string FirstName { get; set; }<\/code><\/pre>\n<p>Indexer: The expressions in this type of method are executed using \u201c[]\u201d indicator when setting or receiving data<br \/>\n\u7d22\u5f15\u5668\uff1a\u5728\u8bbe\u7f6e\u6216\u63a5\u6536\u6570\u636e\u65f6\uff0c\u6b64\u7c7b\u65b9\u6cd5\u4e2d\u7684\u8868\u8fbe\u5f0f\u4f7f\u7528 \u201c[]\u201d \u6307\u793a\u7b26\u6267\u884c<\/p>\n<pre><code>class StringDataStore\n{\n  private string[] strArr = new string[10]; \/\/ internal data storage\n  public string this[int index]\n  {\n    get =&gt; strArr[index];\n    set =&gt; strArr[index] = value;\n  }\n}<\/code><\/pre>\n<p>Operator: The expressions in this type of method are executed when operators like + are used on class operands.<br \/>\n\u8fd0\u7b97\u7b26\uff1a\u5f53\u5bf9\u7c7b\u4f5c\u6570\u4f7f\u7528\u7c7b\u4f3c + \u7684\u8fd0\u7b97\u7b26\u65f6\uff0c\u5c06\u6267\u884c\u6b64\u7c7b\u65b9\u6cd5\u4e2d\u7684\u8868\u8fbe\u5f0f\u3002<\/p>\n<pre><code>  public static Box operator + (Box b, Box c) {\nBox box = new Box();\nbox.length = b.length + c.length;\nbox.breadth = b.breadth + c.breadth;\nbox.height = b.height + c.height;\nreturn box;\n}<\/code><\/pre>\n<p>Apart from the preceding code, a class also contains an inner class:<br \/>\n\u9664\u4e86\u524d\u9762\u7684\u4ee3\u7801\u5916\uff0c\u7c7b\u8fd8\u5305\u542b\u4e00\u4e2a\u5185\u90e8\u7c7b\uff1a<\/p>\n<pre><code> public class A{\npublic string GetName()=&gt; $\u201cVahid is {new B().GetAge()} years old\u201d;\nprivate class B{\npublic int GetAge()=&gt;10;\n}\n}<\/code><\/pre>\n<p>Regardless of the members of a class, part of encapsulation is to assign appropriate access levels to the class or its members. In C# language, there are different access levels which are:<\/p>\n<p>\u65e0\u8bba\u7c7b\u7684\u6210\u5458\u5982\u4f55\uff0c\u5c01\u88c5\u7684\u4e00\u90e8\u5206\u90fd\u662f\u4e3a\u7c7b\u6216\u5176\u6210\u5458\u5206\u914d\u9002\u5f53\u7684\u8bbf\u95ee\u7ea7\u522b\u3002\u5728 C# \u8bed\u8a00\u4e2d\uff0c\u6709\u4e0d\u540c\u7684\u8bbf\u95ee\u7ea7\u522b\uff0c\u5b83\u4eec\u662f\uff1a<\/p>\n<ul>\n<li>\n<p>Public: Members with this access level are available everywhere.<br \/>\n\u516c\u5171\uff1a\u5177\u6709\u6b64\u8bbf\u95ee\u7ea7\u522b\u7684\u6210\u5458\u5728\u4efb\u4f55\u5730\u65b9\u90fd\u53ef\u7528\u3002<\/p>\n<\/li>\n<li>\n<p>Private: Members with this access level are only available inside the class. This access level is the default for class members.<br \/>\nPrivate\uff1a\u5177\u6709\u6b64\u8bbf\u95ee\u7ea7\u522b\u7684\u6210\u5458\u53ea\u80fd\u5728\u7c7b\u5185\u4f7f\u7528\u3002\u6b64\u8bbf\u95ee\u7ea7\u522b\u662f\u7c7b\u6210\u5458\u7684\u9ed8\u8ba4\u8bbf\u95ee\u7ea7\u522b\u3002<\/p>\n<\/li>\n<li>\n<p>Protected: Members with this access level are only available inside the class, and inside classes are derived from this class.<br \/>\n\u53d7\u4fdd\u62a4\uff1a\u5177\u6709\u6b64\u8bbf\u95ee\u7ea7\u522b\u7684\u6210\u5458\u4ec5\u5728\u7c7b\u5185\u90e8\u53ef\u7528\uff0c\u5e76\u4e14\u5185\u90e8\u7c7b\u6d3e\u751f\u81ea\u6b64\u7c7b\u3002<\/p>\n<\/li>\n<li>\n<p>Internal: Members with this access level are only available inside the same assembly.<br \/>\n\u5185\u90e8\uff1a\u5177\u6709\u6b64\u8bbf\u95ee\u7ea7\u522b\u7684\u6210\u5458\u4ec5\u5728\u540c\u4e00\u7a0b\u5e8f\u96c6\u4e2d\u53ef\u7528\u3002<\/p>\n<\/li>\n<li>\n<p>Internal protected: Members with this access level are available within the same class, assembly, or classes derived from this class. This access is internal or protected.<br \/>\nInternal protected\uff1a\u5177\u6709\u6b64\u8bbf\u95ee\u7ea7\u522b\u7684\u6210\u5458\u5728\u540c\u4e00\u4e2a\u7c7b\u3001\u7a0b\u5e8f\u96c6\u6216\u4ece\u6b64\u7c7b\u6d3e\u751f\u7684\u7c7b\u4e2d\u53ef\u7528\u3002\u6b64\u8bbf\u95ee\u6743\u9650\u662f\u5185\u90e8\u8bbf\u95ee\u6743\u9650\u6216\u53d7\u4fdd\u62a4\u8bbf\u95ee\u6743\u9650\u3002<\/p>\n<\/li>\n<li>\n<p>Private protected: Members with this access level are available within the same class or classes derived within the same assembly. This access is internal and protected.<br \/>\nPrivate protected\uff1a\u5177\u6709\u6b64\u8bbf\u95ee\u7ea7\u522b\u7684\u6210\u5458\u5728\u540c\u4e00\u7c7b\u6216\u540c\u4e00\u7a0b\u5e8f\u96c6\u4e2d\u6d3e\u751f\u7684\u7c7b\u4e2d\u53ef\u7528\u3002\u6b64\u8bbf\u95ee\u6743\u9650\u662f\u5185\u90e8\u7684\uff0c\u5e76\u4e14\u53d7\u5230\u4fdd\u62a4\u3002<\/p>\n<\/li>\n<\/ul>\n<p>In addition to access levels, C# language also has a series of Modifiers through which you can slightly change the definition of the class or its members. For example, using sealed makes it impossible to inherit from a class or override a method. When a class is defined as closed, extension methods can be used to expand its capabilities.<\/p>\n<p>\u9664\u4e86\u8bbf\u95ee\u7ea7\u522b\u4e4b\u5916\uff0cC# \u8bed\u8a00\u8fd8\u5177\u6709\u4e00\u7cfb\u5217\u4fee\u9970\u7b26\uff0c\u901a\u8fc7\u8fd9\u4e9b\u4fee\u9970\u7b26\u53ef\u4ee5\u7a0d\u5fae\u66f4\u6539\u7c7b\u6216\u5176\u6210\u5458\u7684\u5b9a\u4e49\u3002\u4f8b\u5982\uff0c\u4f7f\u7528 sealed \u4f7f\u5f97\u65e0\u6cd5\u4ece\u7c7b\u7ee7\u627f\u6216\u91cd\u5199\u65b9\u6cd5\u3002\u5f53\u7c7b\u5b9a\u4e49\u4e3a closed \u65f6\uff0c\u53ef\u4ee5\u4f7f\u7528\u6269\u5c55\u65b9\u6cd5\u6765\u6269\u5c55\u5176\u529f\u80fd\u3002<\/p>\n<p>When the class is defined statically, it is no longer possible to create an instance, and the class is always available to everyone. Also, the abstract is a modifier, when applied to a class, turns the class into an abstract class. When it is attributed to other members, such as methods, it eliminates the possibility of providing an implementation, and child classes are required to provide implementations.<\/p>\n<p>\u5f53\u7c7b\u662f\u9759\u6001\u5b9a\u4e49\u7684\u65f6\uff0c\u5c31\u4e0d\u518d\u53ef\u80fd\u521b\u5efa\u5b9e\u4f8b\uff0c\u5e76\u4e14\u8be5\u7c7b\u59cb\u7ec8\u53ef\u4f9b\u6240\u6709\u4eba\u4f7f\u7528\u3002\u6b64\u5916\uff0c\u62bd\u8c61\u662f\u4e00\u4e2a\u4fee\u9970\u7b26\uff0c\u5f53\u5e94\u7528\u4e8e\u7c7b\u65f6\uff0c\u4f1a\u5c06\u7c7b\u8f6c\u6362\u4e3a\u62bd\u8c61\u7c7b\u3002\u5f53\u5b83\u5f52\u5c5e\u4e8e\u5176\u4ed6\u6210\u5458\uff08\u5982\u65b9\u6cd5\uff09\u65f6\uff0c\u5b83\u6d88\u9664\u4e86\u63d0\u4f9b\u5b9e\u73b0\u7684\u53ef\u80fd\u6027\uff0c\u5e76\u4e14\u9700\u8981\u5b50\u7c7b\u6765\u63d0\u4f9b\u5b9e\u73b0\u3002<\/p>\n<p>Along with classes in C#, there are interfaces that are very similar to abstract classes. All members of interfaces are abstract. Among the similarities between the abstract class and interface, it can be mentioned that neither can be sampled. Along with all the similarities, they also have differences, including the following:<\/p>\n<p>\u9664\u4e86 C# \u4e2d\u7684\u7c7b\u5916\uff0c\u8fd8\u6709\u4e00\u4e9b\u4e0e\u62bd\u8c61\u7c7b\u975e\u5e38\u76f8\u4f3c\u7684\u63a5\u53e3\u3002\u63a5\u53e3\u7684\u6240\u6709\u6210\u5458\u90fd\u662f\u62bd\u8c61\u7684\u3002\u5728\u62bd\u8c61\u7c7b\u548c\u63a5\u53e3\u4e4b\u95f4\u7684\u76f8\u4f3c\u4e4b\u5904\u4e2d\uff0c\u53ef\u4ee5\u63d0\u5230\u4e24\u8005\u90fd\u4e0d\u80fd\u91c7\u6837\u3002\u9664\u4e86\u6240\u6709\u76f8\u4f3c\u4e4b\u5904\u5916\uff0c\u5b83\u4eec\u4e5f\u6709\u4e0d\u540c\u4e4b\u5904\uff0c\u5305\u62ec\uff1a<\/p>\n<ul>\n<li>\n<p>Interfaces can only inherit from interfaces, while abstract classes can inherit from other classes and implement different interfaces.<br \/>\n\u63a5\u53e3\u53ea\u80fd\u7ee7\u627f\u81ea\u63a5\u53e3\uff0c\u800c\u62bd\u8c61\u7c7b\u53ef\u4ee5\u7ee7\u627f\u81ea\u5176\u4ed6\u7c7b\u5e76\u5b9e\u73b0\u4e0d\u540c\u7684\u63a5\u53e3\u3002<\/p>\n<\/li>\n<li>\n<p>Abstract classes can include constructors and destructors, while this possibility is not available for interfaces<br \/>\n\u62bd\u8c61\u7c7b\u53ef\u4ee5\u5305\u542b\u6784\u9020\u51fd\u6570\u548c\u6790\u6784\u51fd\u6570\uff0c\u4f46\u8fd9\u79cd\u53ef\u80fd\u6027\u4e0d\u9002\u7528\u4e8e\u63a5\u53e3<\/p>\n<\/li>\n<\/ul>\n<p>Since C# version 8, interfaces can have default implementations for methods, just like abstract classes.<br \/>\n\u4ece C# \u7248\u672c 8 \u5f00\u59cb\uff0c\u63a5\u53e3\u53ef\u4ee5\u5177\u6709\u65b9\u6cd5\u7684\u9ed8\u8ba4\u5b9e\u73b0\uff0c\u5c31\u50cf\u62bd\u8c61\u7c7b\u4e00\u6837\u3002<\/p>\n<pre><code>public interface IPlayable\n{\n  void Play();\n  void Pause();\n  void Stop() \/\/ default implementation \u9ed8\u8ba4\u5b9e\u73b0\n  {\n    WriteLine(&quot;Default implementation of Stop.&quot;);\n  }\n}<\/code><\/pre>\n<p>In fact, interfaces are a way to connect to each other. When a class implements an interface, it guarantees to provide a set of capabilities. The use of interfaces and abstract classes is very widely used in design patterns.<br \/>\n\u4e8b\u5b9e\u4e0a\uff0c\u63a5\u53e3\u662f\u4e00\u79cd\u76f8\u4e92\u8fde\u63a5\u7684\u65b9\u5f0f\u3002\u5f53\u7c7b\u5b9e\u73b0\u63a5\u53e3\u65f6\uff0c\u5b83\u4fdd\u8bc1\u63d0\u4f9b\u4e00\u7ec4\u529f\u80fd\u3002\u63a5\u53e3\u548c\u62bd\u8c61\u7c7b\u7684\u4f7f\u7528\u5728\u8bbe\u8ba1\u6a21\u5f0f\u4e2d\u5f97\u5230\u4e86\u975e\u5e38\u5e7f\u6cdb\u7684\u5e94\u7528\u3002<\/p>\n<h2>Object orientation SOLID principles<\/h2>\n<h2>\u9762\u5411\u5bf9\u8c61 SOLID \u539f\u5219<\/h2>\n<p>C# programming language is an object-oriented language that provides good facilities for using object-oriented capabilities. Features such as the use of interfaces, inheritance, polymorphism, and so on. The fact that the C# programming language provides such facilities does not guarantee that every code written is by object-oriented principles and has an acceptable quality. Ideally, reaching an appropriate and correct object-oriented design in an extensive system will be challenging and require much scrutiny and precision.<\/p>\n<p>C# \u7f16\u7a0b\u8bed\u8a00\u662f\u4e00\u79cd\u9762\u5411\u5bf9\u8c61\u7684\u8bed\u8a00\uff0c\u5b83\u4e3a\u4f7f\u7528\u9762\u5411\u5bf9\u8c61\u7684\u529f\u80fd\u63d0\u4f9b\u4e86\u826f\u597d\u7684\u5de5\u5177\u3002\u529f\u80fd\uff0c\u4f8b\u5982\u4f7f\u7528\u63a5\u53e3\u3001\u7ee7\u627f\u3001\u591a\u6001\u6027\u7b49\u3002C# \u7f16\u7a0b\u8bed\u8a00\u63d0\u4f9b\u6b64\u7c7b\u5de5\u5177\u8fd9\u4e00\u4e8b\u5b9e\u5e76\u4e0d\u80fd\u4fdd\u8bc1\u7f16\u5199\u7684\u6bcf\u6bb5\u4ee3\u7801\u90fd\u9075\u5faa\u9762\u5411\u5bf9\u8c61\u539f\u5219\u5e76\u5177\u6709\u53ef\u63a5\u53d7\u7684\u8d28\u91cf\u3002\u7406\u60f3\u60c5\u51b5\u4e0b\uff0c\u5728\u4e00\u4e2a\u5e7f\u6cdb\u7684\u7cfb\u7edf\u4e2d\u5b9e\u73b0\u9002\u5f53\u548c\u6b63\u786e\u7684\u9762\u5411\u5bf9\u8c61\u8bbe\u8ba1\u5c06\u5177\u6709\u6311\u6218\u6027\uff0c\u5e76\u4e14\u9700\u8981\u5927\u91cf\u7684\u5ba1\u67e5\u548c\u7cbe\u786e\u6027\u3002<\/p>\n<p>Various principles have been introduced to produce the system according to the correct principles and guidelines of object orientation. One of these principles is the SOLID principle. SOLID actually consists of five different principles, which are:<\/p>\n<p>\u5df2\u7ecf\u5f15\u5165\u4e86\u5404\u79cd\u539f\u5219\uff0c\u4ee5\u6839\u636e\u9762\u5411\u5bf9\u8c61\u7684\u6b63\u786e\u539f\u5219\u548c\u51c6\u5219\u6765\u751f\u6210\u7cfb\u7edf\u3002\u8fd9\u4e9b\u539f\u5219\u4e4b\u4e00\u662f SOLID \u539f\u5219\u3002SOLID \u5b9e\u9645\u4e0a\u7531\u4e94\u4e2a\u4e0d\u540c\u7684\u539f\u5219\u7ec4\u6210\uff0c\u5b83\u4eec\u662f\uff1a<\/p>\n<ul>\n<li>\n<p>Single Responsibility Principle (SRP)<br \/>\n\u5355\u4e00\u8d23\u4efb\u539f\u5219 \uff08SRP\uff09<\/p>\n<\/li>\n<li>\n<p>Open\/Close Principle (OCP)<br \/>\n\u5f00\/\u5173\u539f\u5219 \uff08OCP\uff09<\/p>\n<\/li>\n<li>\n<p>Liskov Substitution Principle (LSP)<br \/>\n\u91cc\u65af\u79d1\u592b\u66ff\u4ee3\u539f\u5219 \uff08LSP\uff09<\/p>\n<\/li>\n<li>\n<p>Interface Segregation Principle (ISP)<br \/>\n\u63a5\u53e3\u5206\u79bb\u539f\u5219 \uff08ISP\uff09<\/p>\n<\/li>\n<li>\n<p>Dependency Inversion Principle (DSP)<br \/>\n\u4f9d\u8d56\u5173\u7cfb\u5012\u7f6e\u539f\u5219 \uff08DSP\uff09<\/p>\n<\/li>\n<\/ul>\n<p>The title SOLID also consists of the first letters of each of the preceding five principles. These principles help the written code to be of good quality and to maintain the code at an acceptable level. In the following, each of these principles is explained:<br \/>\n\u6807\u9898 SOLID \u4e5f\u7531\u4e0a\u8ff0\u4e94\u4e2a\u539f\u5219\u4e2d\u6bcf\u4e2a\u539f\u5219\u7684\u9996\u5b57\u6bcd\u7ec4\u6210\u3002\u8fd9\u4e9b\u539f\u5219\u6709\u52a9\u4e8e\u7f16\u5199\u7684\u4ee3\u7801\u5177\u6709\u826f\u597d\u7684\u8d28\u91cf\uff0c\u5e76\u5c06\u4ee3\u7801\u4fdd\u6301\u5728\u53ef\u63a5\u53d7\u7684\u6c34\u5e73\u3002\u4e0b\u9762\u5c06\u89e3\u91ca\u8fd9\u4e9b\u539f\u5219\u4e2d\u7684\u6bcf\u4e00\u4e2a\uff1a<\/p>\n<h4>Single Responsibility Principle<\/h4>\n<h4>\u5355\u4e00\u8d23\u4efb\u539f\u5219<\/h4>\n<p>This principle states that each class should have only one task, which by nature will have one reason to change the class. When this principle is not followed, a class will contain a large amount of code to be changed if there is a need in the system. Making changes to this class will lead to the re-execution of the tests. On the other hand, by observing this principle, a big problem is divided into several smaller problems, and each issue is implemented in the form of a class. Therefore, making changes in the system will lead to making changes in one of these small classes, and it will only be necessary to run the tests related to this small class again. The principle of SRP is very similar to the principle in object orientation called SoC1.<\/p>\n<p>\u8be5\u539f\u5219\u6307\u51fa\uff0c\u6bcf\u4e2a\u7c7b\u5e94\u8be5\u53ea\u6709\u4e00\u4e2a\u4efb\u52a1\uff0c\u800c\u8be5\u4efb\u52a1\u672c\u8d28\u4e0a\u53ea\u6709\u4e00\u4e2a\u66f4\u6539\u7c7b\u7684\u7406\u7531\u3002\u5982\u679c\u4e0d\u9075\u5faa\u6b64\u539f\u5219\uff0c\u5982\u679c\u7cfb\u7edf\u6709\u9700\u8981\uff0c\u4e00\u4e2a\u7c7b\u5c06\u5305\u542b\u5927\u91cf\u9700\u8981\u66f4\u6539\u7684\u4ee3\u7801\u3002\u5bf9\u6b64\u7c7b\u8fdb\u884c\u66f4\u6539\u5c06\u5bfc\u81f4\u91cd\u65b0\u6267\u884c\u6d4b\u8bd5\u3002\u53e6\u4e00\u65b9\u9762\uff0c\u901a\u8fc7\u9075\u5b88\u8fd9\u4e2a\u539f\u5219\uff0c\u4e00\u4e2a\u5927\u95ee\u9898\u88ab\u5206\u6210\u51e0\u4e2a\u5c0f\u95ee\u9898\uff0c\u6bcf\u4e2a\u95ee\u9898\u90fd\u4ee5\u7c7b\u7684\u5f62\u5f0f\u5b9e\u73b0\u3002\u56e0\u6b64\uff0c\u5728\u7cfb\u7edf\u4e2d\u8fdb\u884c\u66f4\u6539\u5c06\u5bfc\u81f4\u5bf9\u5176\u4e2d\u4e00\u4e2a\u5c0f\u7c7b\u8fdb\u884c\u66f4\u6539\uff0c\u5e76\u4e14\u53ea\u9700\u8981\u518d\u6b21\u8fd0\u884c\u4e0e\u8be5\u5c0f\u7c7b\u76f8\u5173\u7684\u6d4b\u8bd5\u5373\u53ef\u3002SRP \u7684\u539f\u7406\u4e0e\u9762\u5411\u5bf9\u8c61\u7684\u539f\u7406\u975e\u5e38\u76f8\u4f3c\uff0c\u79f0\u4e3a SoC1\u3002<\/p>\n<p>For example, consider the following code:<br \/>\n\u4f8b\u5982\uff0c\u8bf7\u8003\u8651\u4ee5\u4e0b\u4ee3\u7801\uff1a<\/p>\n<pre><code>public class WrongSRP\n{\n\n  public string FirstName { get; set; }\n  public string LastName { get; set; }\n  public string Email { get; set; }\n  public static List&lt;WrongSRP&gt; Users { get; set; } = new List&lt;WrongSRP&gt;();\n\n  public void NewUser(WrongSRP User)\n  {\n  Users.Add(User);\n  SendEmail(User.Email, &quot;Account Created&quot;, &quot;Your new account created&quot;);\n  }\n\n  public void SendEmail(string email, string subject, string body)\n  {\n  \/\/Send email\n  }\n}<\/code><\/pre>\n<p>Suppose it is requested to design and implement a mechanism to create a new user. It is necessary to send an email after creating a user account. The preceding code has two methods called NewUser to create a new user and SendEmail to send an email. There are two different behaviors in the same class that are not directly related to each other. In other words, sending an e-mail is not directly related to the user entity, and the presence of this method in this class violates the SRP principle. Because this class is no longer responsible for only one task, and apart from managing user-related requests, it is also responsible for sending emails. The preceding design will cause the codes to change if the email-sending process changes. For example, the email service provider changes. In order to modify this code, the preceding code can be rewritten as follows:<\/p>\n<p>\u5047\u8bbe\u8bf7\u6c42\u8bbe\u8ba1\u548c\u5b9e\u73b0\u4e00\u79cd\u673a\u5236\u6765\u521b\u5efa\u65b0\u7528\u6237\u3002\u521b\u5efa\u7528\u6237\u5e10\u6237\u540e\uff0c\u9700\u8981\u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u3002\u4e0a\u8ff0\u4ee3\u7801\u6709\u4e24\u4e2a\u65b9\u6cd5\uff0c\u5206\u522b\u79f0\u4e3a NewUser \u6765\u521b\u5efa\u65b0\u7528\u6237\uff0c\u53e6\u4e00\u4e2a\u65b9\u6cd5\u79f0\u4e3a SendEmail \u6765\u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u3002\u540c\u4e00\u7c7b\u4e2d\u6709\u4e24\u79cd\u4e0d\u540c\u7684\u884c\u4e3a\uff0c\u5b83\u4eec\u5f7c\u6b64\u4e4b\u95f4\u6ca1\u6709\u76f4\u63a5\u5173\u7cfb\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u4e0e\u7528\u6237\u5b9e\u4f53\u6ca1\u6709\u76f4\u63a5\u5173\u7cfb\uff0c\u5e76\u4e14\u6b64\u7c7b\u4e2d\u5b58\u5728\u6b64\u65b9\u6cd5\u8fdd\u53cd\u4e86 SRP \u539f\u5219\u3002\u56e0\u4e3a\u8fd9\u4e2a\u7c7b\u4e0d\u518d\u53ea\u8d1f\u8d23\u4e00\u4e2a\u4efb\u52a1\uff0c\u9664\u4e86\u7ba1\u7406\u4e0e\u7528\u6237\u76f8\u5173\u7684\u8bf7\u6c42\u5916\uff0c\u5b83\u8fd8\u8d1f\u8d23\u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u3002\u5982\u679c\u7535\u5b50\u90ae\u4ef6\u53d1\u9001\u8fc7\u7a0b\u53d1\u751f\u53d8\u5316\uff0c\u4e0a\u8ff0\u8bbe\u8ba1\u5c06\u5bfc\u81f4\u4ee3\u7801\u53d1\u751f\u53d8\u5316\u3002\u4f8b\u5982\uff0c\u7535\u5b50\u90ae\u4ef6\u670d\u52a1\u63d0\u4f9b\u5546\u4f1a\u53d1\u751f\u53d8\u5316\u3002\u4e3a\u4e86\u4fee\u6539\u6b64\u4ee3\u7801\uff0c\u53ef\u4ee5\u6309\u5982\u4e0b\u65b9\u5f0f\u91cd\u5199\u4e0a\u8ff0\u4ee3\u7801\uff1a<\/p>\n<pre><code>public class SRP\n{\n  public string FirstName { get; set; }\n  public string Email { get; set; }\n  public string LastName { get; set; }\n  public static List&lt;WrongSRP&gt; Users { get; set; } = new List&lt;WrongSRP&gt;();\n\n  public void NewUser(WrongSRP User)\n  {\n  Users.Add(User);\n  new EmailService()\n  .SendEmail(User.Email,&quot;Account Created&quot;,&quot;Your new account created&quot;);\n  }\n}\n\npublic class EmailService\n{\n  public void SendEmail(string email, string subject, string body)\n  {\n    \/\/Send email\n  }\n}<\/code><\/pre>\n<p>As can be seen in the preceding code, the task of sending emails has been transferred to the EmailService class, and with this rewrite, the SRP principle has been respected, and it will not have the problems of the previous code.<br \/>\n\u4ece\u524d\u9762\u7684\u4ee3\u7801\u4e2d\u53ef\u4ee5\u770b\u51fa\uff0c\u53d1\u9001\u90ae\u4ef6\u7684\u4efb\u52a1\u5df2\u7ecf\u8f6c\u79fb\u5230\u4e86 EmailService \u7c7b\uff0c\u901a\u8fc7\u8fd9\u6b21\u91cd\u5199\uff0c\u5c0a\u91cd\u4e86 SRP \u539f\u5219\uff0c\u4e0d\u4f1a\u6709\u4e4b\u524d\u4ee3\u7801\u7684\u95ee\u9898\u3002<\/p>\n<h4>Open\/Close Principal<\/h4>\n<h4>\u5f00\/\u5173\u539f\u5219 \uff08OCP\uff09<\/h4>\n<p>This principle states that a class should be open for extension and closed for modification. In other words, when a class is implemented, and other parts of the system start using this class, it should not be changed. It is clear that making changes in this class can cause problems in the parts of the system. If there is a need to add new capabilities to the class, these should be added to it by expanding the class. In this case, the parts of the system that uses this class will not be affected by the applied changes, and in order to test new codes, only new parts will be needed to be tested.<\/p>\n<p>\u6b64\u539f\u5219\u6307\u51fa\uff0c\u7c7b\u5e94\u4e3a open for extension\uff0cshut for modification\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u5f53\u5b9e\u73b0\u4e00\u4e2a\u7c7b\uff0c\u5e76\u4e14\u7cfb\u7edf\u7684\u5176\u4ed6\u90e8\u5206\u5f00\u59cb\u4f7f\u7528\u8fd9\u4e2a\u7c7b\u65f6\uff0c\u5b83\u4e0d\u5e94\u8be5\u88ab\u6539\u53d8\u3002\u5f88\u660e\u663e\uff0c\u5728\u6b64\u7c7b\u4e2d\u8fdb\u884c\u66f4\u6539\u53ef\u80fd\u4f1a\u5bfc\u81f4\u7cfb\u7edf\u7684\u67d0\u4e9b\u90e8\u5206\u51fa\u73b0\u95ee\u9898\u3002\u5982\u679c\u9700\u8981\u5411\u7c7b\u6dfb\u52a0\u65b0\u529f\u80fd\uff0c\u5219\u5e94\u901a\u8fc7\u6269\u5c55\u7c7b\u6765\u5c06\u8fd9\u4e9b\u529f\u80fd\u6dfb\u52a0\u5230\u7c7b\u4e2d\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u4f7f\u7528\u6b64\u7c7b\u7684\u7cfb\u7edf\u90e8\u5206\u5c06\u4e0d\u4f1a\u53d7\u5230\u5e94\u7528\u7684\u66f4\u6539\u7684\u5f71\u54cd\uff0c\u5e76\u4e14\u4e3a\u4e86\u6d4b\u8bd5\u65b0\u4ee3\u7801\uff0c\u53ea\u9700\u8981\u6d4b\u8bd5\u65b0\u90e8\u5206\u3002<\/p>\n<p>For example, suppose you are asked to write a class to calculate employee salaries. In the initial plan of this requirement, it is stated that the working hours of all employees must be multiplied by 1000, and this way, salaries are calculated. With this explanation, the following code is written:<\/p>\n<p>\u4f8b\u5982\uff0c\u5047\u8bbe\u60a8\u88ab\u8981\u6c42\u7f16\u5199\u4e00\u4e2a\u7c7b\u6765\u8ba1\u7b97\u5458\u5de5\u5de5\u8d44\u3002\u5728\u6b64\u8981\u6c42\u7684\u521d\u59cb\u8ba1\u5212\u4e2d\uff0c\u89c4\u5b9a\u6240\u6709\u5458\u5de5\u7684\u5de5\u4f5c\u65f6\u95f4\u5fc5\u987b\u4e58\u4ee5 1000\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u8ba1\u7b97\u51fa\u5de5\u8d44\u3002\u901a\u8fc7\u6b64\u8bf4\u660e\uff0c\u7f16\u5199\u4e86\u4ee5\u4e0b\u4ee3\u7801\uff1a<\/p>\n<pre><code>public class WrongOCP\n{\n  public string Name { get; set; }\n  public decimal CalculateSalary(decimal hours) =&gt; hours * 1000;\n}<\/code><\/pre>\n<p>The preceding code has a method called CalculateSalary which calculates the salary of each person by receiving the working hours. After this code has been used for some time, it is said that a new type of employee called a manager has been defined in the system. For them, the working hours should be multiplied by 1500, and for others, it should be multiplied by 1000. Therefore, to cover this need, we change the preceding code as follows:<\/p>\n<p>\u524d\u9762\u7684\u4ee3\u7801\u6709\u4e00\u4e2a\u540d\u4e3a CalculateSalary \u7684\u65b9\u6cd5\uff0c\u5b83\u901a\u8fc7\u63a5\u6536\u5de5\u4f5c\u65f6\u95f4\u6765\u8ba1\u7b97\u6bcf\u4e2a\u4eba\u7684\u5de5\u8d44\u3002\u6b64\u4ee3\u7801\u4f7f\u7528\u4e00\u6bb5\u65f6\u95f4\u540e\uff0c\u636e\u8bf4\u7cfb\u7edf\u4e2d\u5b9a\u4e49\u4e86\u4e00\u79cd\u79f0\u4e3a\u7ecf\u7406\u7684\u65b0\u578b\u5458\u5de5\u3002\u5bf9\u4ed6\u4eec\u6765\u8bf4\uff0c\u5de5\u4f5c\u65f6\u95f4\u5e94\u8be5\u4e58\u4ee5 1500\uff0c\u5bf9\u5176\u4ed6\u4eba\u6765\u8bf4\uff0c\u5e94\u8be5\u4e58\u4ee5 1000\u3002\u56e0\u6b64\uff0c\u4e3a\u4e86\u6ee1\u8db3\u8fd9\u4e00\u9700\u6c42\uff0c\u6211\u4eec\u6309\u5982\u4e0b\u65b9\u5f0f\u66f4\u6539\u4e86\u524d\u9762\u7684\u4ee3\u7801\uff1a<\/p>\n<pre><code>public class WrongOCP\n{\n    public string Name { get; set; }\n    public string UserType { get; set; }\n\n    public decimal CalculateSalary(decimal hours)\n    {\n    if (UserType == &quot;Manager&quot;)\n    return hours * 1500;\n    return hours * 1000;\n    }\n}<\/code><\/pre>\n<p>To add this new feature to the class, we changed the existing code, and this violates the OCP principle. By making these changes in the class, all parts of the system that use this class will be affected. To cover the requirement raised in the form of the original OCP, the preceding code can be rewritten as follows:<\/p>\n<p>\u4e3a\u4e86\u5c06\u8fd9\u4e2a\u65b0\u529f\u80fd\u6dfb\u52a0\u5230\u7c7b\u4e2d\uff0c\u6211\u4eec\u66f4\u6539\u4e86\u73b0\u6709\u4ee3\u7801\uff0c\u8fd9\u8fdd\u53cd\u4e86 OCP \u539f\u5219\u3002\u901a\u8fc7\u5728\u7c7b\u4e2d\u8fdb\u884c\u8fd9\u4e9b\u66f4\u6539\uff0c\u4f7f\u7528\u6b64\u7c7b\u7684\u7cfb\u7edf\u7684\u6240\u6709\u90e8\u5206\u90fd\u5c06\u53d7\u5230\u5f71\u54cd\u3002\u4e3a\u4e86\u6db5\u76d6\u4ee5\u539f\u59cb OCP \u5f62\u5f0f\u63d0\u51fa\u7684\u8981\u6c42\uff0c\u53ef\u4ee5\u6309\u5982\u4e0b\u65b9\u5f0f\u91cd\u5199\u524d\u9762\u7684\u4ee3\u7801\uff1a<\/p>\n<pre><code>public abstract class OCP\n{\n  protected OCP(string name) =&gt; Name = name;\n  public string Name { get; set; }\n  public abstract decimal CalculateSalary(decimal hours);\n}\n\npublic class Manager : OCP\n{\n  public Manager(string name) : base(name) { }\n  public override decimal CalculateSalary(decimal hours) =&gt; hours * 1500;\n}\n\npublic class Employee : OCP\n{\n  public Employee(string name) : base(name) { }\n  public override decimal CalculateSalary(decimal hours) =&gt; hours * 1000;\n}<\/code><\/pre>\n<p>In the preceding code, if we want to add the role of a consultant, for example, it is enough to create a new class for the consultant and define the process of calculating his salary without touching the existing codes. With these words, new functionality is added without changing the current codes.<\/p>\n<p>\u5728\u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\uff0c\u4f8b\u5982\uff0c\u5982\u679c\u6211\u4eec\u60f3\u6dfb\u52a0\u987e\u95ee\u7684\u89d2\u8272\uff0c\u53ea\u9700\u4e3a\u987e\u95ee\u521b\u5efa\u4e00\u4e2a\u65b0\u7c7b\u5e76\u5b9a\u4e49\u8ba1\u7b97\u5176\u85aa\u6c34\u7684\u8fc7\u7a0b\u5c31\u8db3\u591f\u4e86\uff0c\u800c\u65e0\u9700\u89e6\u53ca\u73b0\u6709\u4ee3\u7801\u3002\u4f7f\u7528\u8fd9\u4e9b\u8bcd\uff0c\u53ef\u4ee5\u5728\u4e0d\u66f4\u6539\u5f53\u524d\u4ee3\u7801\u7684\u60c5\u51b5\u4e0b\u6dfb\u52a0\u65b0\u529f\u80fd\u3002<\/p>\n<h4>Liskov Substitution Principle<\/h4>\n<h4>\u91cc\u65af\u79d1\u592b\u66ff\u4ee3\u539f\u5219 \uff08LSP\uff09<\/h4>\n<p>This principle states that the objects of the child class should be able to replace the parent class so there is no change in the final result. To make the matter clear, let us assume that we are asked to design an infrastructure through which the contents of various files can be read and written to these files. It is also stated that a message should be displayed to the user before reading and writing in text files. For this purpose, the following code can be considered:<\/p>\n<p>\u8be5\u539f\u5219\u6307\u51fa\uff0c\u5b50\u7c7b\u7684\u5bf9\u8c61\u5e94\u8be5\u80fd\u591f\u66ff\u6362\u7236\u7c7b\uff0c\u56e0\u6b64\u6700\u7ec8\u7ed3\u679c\u6ca1\u6709\u53d8\u5316\u3002\u4e3a\u4e86\u6e05\u695a\u5730\u8bf4\u660e\u8fd9\u4e2a\u95ee\u9898\uff0c\u8ba9\u6211\u4eec\u5047\u8bbe\u6211\u4eec\u88ab\u8981\u6c42\u8bbe\u8ba1\u4e00\u4e2a\u57fa\u7840\u8bbe\u65bd\uff0c\u901a\u8fc7\u8be5\u57fa\u7840\u8bbe\u65bd\uff0c\u53ef\u4ee5\u8bfb\u53d6\u548c\u5199\u5165\u5404\u79cd\u6587\u4ef6\u7684\u5185\u5bb9\u3002\u8fd8\u6307\u51fa\uff0c\u5728\u8bfb\u53d6\u548c\u5199\u5165\u6587\u672c\u6587\u4ef6\u4e4b\u524d\uff0c\u5e94\u5411\u7528\u6237\u663e\u793a\u4e00\u6761\u6d88\u606f\u3002\u4e3a\u6b64\uff0c\u53ef\u4ee5\u8003\u8651\u4ee5\u4e0b\u4ee3\u7801\uff1a<\/p>\n<pre><code>public class FileManager\n{\n  public virtual void Read()=&gt; Console.WriteLine(&quot;Reading from file...&quot;);\n  public virtual void Write()=&gt; Console.WriteLine(&quot;Writting to file...&quot;);\n  }\n\n  public class TextFileManager : FileManager\n  {\n    public override void Read()\n  {\n    Console.WriteLine(&quot;Reading text file...&quot;);\n    base.Read();\n  }\n  public override void Write()\n  {\n    Console.WriteLine(&quot;Writting to text file...&quot;);\n    base.Write();\n  }\n}<\/code><\/pre>\n<p>After some time, it is stated that the possibility of writing in XML files will be removed, and there is no need to present the writing behavior for XML files to the user. With these conditions, the preceding code changes as the following:<\/p>\n<p>\u4e00\u6bb5\u65f6\u95f4\u540e\uff0c\u58f0\u660e\u5c06\u6d88\u9664\u5199\u5165 XML \u6587\u4ef6\u7684\u53ef\u80fd\u6027\uff0c\u5e76\u4e14\u65e0\u9700\u5411\u7528\u6237\u63d0\u4f9b XML \u6587\u4ef6\u7684\u5199\u5165\u884c\u4e3a\u3002\u5728\u8fd9\u4e9b\u6761\u4ef6\u4e0b\uff0c\u524d\u9762\u7684\u4ee3\u7801\u5c06\u66f4\u6539\u5982\u4e0b\uff1a<\/p>\n<pre><code>public class FileManager\n\n{\n  public virtual void Read() =&gt; Console.WriteLine(&quot;Reading from file...&quot;);\n  public virtual void Write() =&gt; Console.WriteLine(&quot;Writting to file...&quot;);\n}\n\npublic class TextFileManager : FileManager\n  {\n  public override void Read()\n  {\n  Console.WriteLine(&quot;Reading from text file...&quot;);\n  base.Read();\n  }\n\n  public override void Write()\n  {\n  Console.WriteLine(&quot;Writting to text file...&quot;);\n  base.Write();\n  }\n}\n\npublic class XmlFileManager : FileManager\n{\n  public override void Write()=&gt; throw new NotImplementedException();\n}<\/code><\/pre>\n<p>Now that the preceding class has been added for XmlFileManager, the following problem appears:<br \/>\n\u73b0\u5728\uff0c\u5df2\u4e3a XmlFileManager \u6dfb\u52a0\u4e86\u524d\u9762\u7684\u7c7b\uff0c\u6b64\u65f6\u4f1a\u51fa\u73b0\u4ee5\u4e0b\u95ee\u9898\uff1a<\/p>\n<pre><code>FileManager fm = new XmlFileManager();\nfm.Read();\nfm.Write();\/\/ Runtime error \u8fd0\u884c\u65f6\u9519\u8bef<\/code><\/pre>\n<p>In the preceding code, when we want to call the Write method, we will encounter a NotImplementedException error, so it is not possible to replace the child class object, that is, the XmlFileManager class object, with the parent class object, that is, the FileManager class, and this replacement will change the final result. Because if we worked only with the parent class in the preceding code (FileManager fm = new FileManager()), a result would be obtained. In this case, the LSP principle is violated.<\/p>\n<p>\u5728\u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\uff0c\u5f53\u6211\u4eec\u8981\u8c03\u7528 Write \u65b9\u6cd5\u65f6\uff0c\u4f1a\u9047\u5230\u4e00\u4e2a NotImplementedException \u9519\u8bef\uff0c\u6240\u4ee5\u65e0\u6cd5\u5c06\u5b50\u7c7b\u5bf9\u8c61\uff08\u5373 XmlFileManager \u7c7b\u5bf9\u8c61\uff09\u66ff\u6362\u4e3a\u7236\u7c7b\u5bf9\u8c61\uff08\u5373 FileManager \u7c7b\uff09\uff0c\u800c\u8fd9\u79cd\u66ff\u6362\u4f1a\u6539\u53d8\u6700\u7ec8\u7684\u7ed3\u679c\u3002\u56e0\u4e3a\u5982\u679c\u6211\u4eec\u53ea\u4f7f\u7528\u524d\u9762\u4ee3\u7801\u4e2d\u7684\u7236\u7c7b \uff08FileManager fm = new FileManager\uff08\uff09\uff09\uff0c\u5c31\u4f1a\u5f97\u5230\u4e00\u4e2a\u7ed3\u679c\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u8fdd\u53cd\u4e86 LSP \u539f\u5219\u3002<\/p>\n<p>To modify the preceding structure, the code can be changed as the following:<br \/>\n\u8981\u4fee\u6539\u4e0a\u8ff0\u7ed3\u6784\uff0c\u53ef\u4ee5\u6309\u5982\u4e0b\u65b9\u5f0f\u66f4\u6539\u4ee3\u7801\uff1a<\/p>\n<pre><code>public interface IFileReader\n{\n  void Read();\n}\n\npublic interface IFileWriter\n{\n  void Write();\n}\n\npublic class FileManager : IFileReader, IFileWriter\n{\n  public void Read() =&gt; Console.WriteLine(&quot;Reading from file...&quot;);\n  public void Write() =&gt; Console.WriteLine(&quot;Writting to file...&quot;);\n}\n\npublic class TextFileManager : IFileReader, IFileWriter\n{\n  public void Read() =&gt; Console.WriteLine(&quot;Reading text file...&quot;);\n  public void Write() =&gt; Console.WriteLine(&quot;Writting to text file...&quot;);\n}\n\npublic class XmlFileManager : IFileReader\n{\n  public void Read() =&gt; Console.WriteLine(&quot;Reading from file...&quot;);\n}<\/code><\/pre>\n<p>In the preceding code, two different interfaces called IFileReader and IFileWriter are introduced. Each class has implemented these interfaces according to its coverage level. Since there was no need to write the Xml files, this class only implemented IFileReader. According to the change in the preceding code, it can be used as the following:<\/p>\n<p>\u5728\u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\uff0c\u5f15\u5165\u4e86\u4e24\u4e2a\u4e0d\u540c\u7684\u63a5\u53e3\uff0c\u5206\u522b\u79f0\u4e3a IFileReader \u548c IFileWriter\u3002\u6bcf\u4e2a\u7c7b\u90fd\u6839\u636e\u5176\u8986\u76d6\u7387\u7ea7\u522b\u5b9e\u73b0\u4e86\u8fd9\u4e9b\u63a5\u53e3\u3002\u7531\u4e8e\u4e0d\u9700\u8981\u7f16\u5199 Xml \u6587\u4ef6\uff0c\u56e0\u6b64\u6b64\u7c7b\u4ec5\u5b9e\u73b0 IFileReader\u3002\u6839\u636e\u4e0a\u8ff0\u4ee3\u7801\u4e2d\u7684\u66f4\u6539\uff0c\u53ef\u4ee5\u6309\u5982\u4e0b\u65b9\u5f0f\u4f7f\u7528\uff1a<\/p>\n<pre><code>IFileReader xmlReader = new XmlFileManager();\nxmlReader.Read();<\/code><\/pre>\n<p>As you can see, in the preceding code, the child class has replaced the parent class, and there has been no change in the result. In the prior structure, since XmlFileManager has not implemented the IFileWriter interface, there is no error or change in the final result. In this way, the LSP principle has been observed.<\/p>\n<p>\u5982\u60a8\u6240\u89c1\uff0c\u5728\u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\uff0c\u5b50\u7c7b\u5df2\u66ff\u6362\u7236\u7c7b\uff0c\u7ed3\u679c\u6ca1\u6709\u53d8\u5316\u3002\u5728\u524d\u9762\u7684\u7ed3\u6784\u4e2d\uff0c\u7531\u4e8e XmlFileManager \u5c1a\u672a\u5b9e\u73b0 IFileWriter \u63a5\u53e3\uff0c\u56e0\u6b64\u6700\u7ec8\u7ed3\u679c\u4e2d\u6ca1\u6709\u9519\u8bef\u6216\u66f4\u6539\u3002\u8fd9\u6837\uff0c\u5c31\u9075\u5b88\u4e86 LSP \u539f\u5219\u3002<\/p>\n<h4>Interface segregation principle<\/h4>\n<h4>\u63a5\u53e3\u9694\u79bb\u539f\u5219<\/h4>\n<p>This principle states that users of an interface would not have to implement features and methods they do not need. Suppose we are implementing a payroll system. In order to calculate the salaries of employees, a series of attributes are considered for them and written as follows:<\/p>\n<p>\u8be5\u539f\u5219\u6307\u51fa\uff0c\u63a5\u53e3\u7684\u7528\u6237\u4e0d\u5fc5\u5b9e\u73b0\u4ed6\u4eec\u4e0d\u9700\u8981\u7684\u529f\u80fd\u548c\u65b9\u6cd5\u3002\u5047\u8bbe\u6211\u4eec\u6b63\u5728\u5b9e\u65bd\u4e00\u4e2a\u5de5\u8d44\u5355\u7cfb\u7edf\u3002\u4e3a\u4e86\u8ba1\u7b97\u5458\u5de5\u7684\u5de5\u8d44\uff0c\u8003\u8651\u4e86\u4e00\u7cfb\u5217\u5c5e\u6027\uff0c\u5e76\u5199\u6210\u5982\u4e0b\uff1a<\/p>\n<pre><code>public interface IWorker\n{\n  public string Name { get; set; }\n  public int MonthlySalary { get; set; }\n  public int HourlySalary { get; set; }\n  public int HoursInMonth { get; set; }\n}<\/code><\/pre>\n<p>On the other hand, there are two types of employees in the system. Full-time and part-time employees. Salaries of full-time employees are calculated by adding 10% to MonthlySalary, and HourlySalary and HoursInMonth are useless for these employees. For part-time employees, salaries are calculated from the product of HourlySalary multiplied by HoursInMonth, and MonthlySalary is useless for this type of employee. To implement these types of employees, the following code is written:<\/p>\n<p>\u53e6\u4e00\u65b9\u9762\uff0c\u7cfb\u7edf\u4e2d\u6709\u4e24\u79cd\u7c7b\u578b\u7684\u5458\u5de5\u3002\u5168\u804c\u548c\u517c\u804c\u5458\u5de5\u3002\u5168\u804c\u5458\u5de5\u7684\u5de5\u8d44\u662f\u901a\u8fc7\u5728 MonthlySalary \u4e0a\u589e\u52a0 10% \u6765\u8ba1\u7b97\u7684\uff0cHourlySalary \u548c HoursInMonth \u5bf9\u8fd9\u4e9b\u5458\u5de5\u6beb\u65e0\u7528\u5904\u3002\u5bf9\u4e8e\u517c\u804c\u5458\u5de5\uff0c\u5de5\u8d44\u662f\u6839\u636e HourlySalary \u4e58\u4ee5 HoursInMonth \u7684\u4e58\u79ef\u8ba1\u7b97\u7684\uff0c\u800c MonthlySalary \u5bf9\u8fd9\u79cd\u7c7b\u578b\u7684\u5458\u5de5\u6beb\u65e0\u7528\u5904\u3002\u4e3a\u4e86\u5b9e\u73b0\u8fd9\u4e9b\u7c7b\u578b\u7684\u5458\u5de5\uff0c\u7f16\u5199\u4e86\u4ee5\u4e0b\u4ee3\u7801\uff1a<\/p>\n<pre><code>public class FullTimeWorker: IWorker\n{\n    public string Name { get; set; }\n    public int MonthlySalary { get; set; }\n    public int HourlySalary {\n    get =&gt; throw new NotImplementedException();\n    set =&gt; throw new NotImplementedException();\n    }\n\n  public int HoursInMonth {\n    get =&gt; throw new NotImplementedException();\n    set =&gt; throw new NotImplementedException();\n  }\n\n  public int CalculateSalary()=&gt;MonthlySalary+(MonthlySalary * 10 \/ 100);\n}\n\npublic class PartTimeWorker : IWorker\n{\n  public string Name { get; set; }\n  public int MonthlySalary {\n  get =&gt; throw new NotImplementedException();\n  set =&gt; throw new NotImplementedException();\n    }\n\n  public int HourlySalary { get; set; }\n  public int HoursInMonth { get; set; }\n\n  public int CalculateSalary() =&gt; HourlySalary * HoursInMonth;\n\n}<\/code><\/pre>\n<p>As can be seen in the preceding code, the FullTimeWorker and PartTimeWorker classes have features that are useless for them, but since they need to implement the IWorker interface, these features are placed for them. Hence, the ISP principle is violated. In order to modify this structure, it is necessary to define smaller and more appropriate interfaces. Therefore, the following interfaces can be considered:<\/p>\n<p>\u4ece\u524d\u9762\u7684\u4ee3\u7801\u4e2d\u53ef\u4ee5\u770b\u51fa\uff0cFullTimeWorker \u548c PartTimeWorker \u7c7b\u5177\u6709\u5bf9\u5b83\u4eec\u65e0\u7528\u7684\u529f\u80fd\uff0c\u4f46\u7531\u4e8e\u5b83\u4eec\u9700\u8981\u5b9e\u73b0 IWorker \u63a5\u53e3\uff0c\u56e0\u6b64\u4e3a\u5b83\u4eec\u653e\u7f6e\u4e86\u8fd9\u4e9b\u529f\u80fd\u3002\u56e0\u6b64\uff0c\u8fdd\u53cd\u4e86 ISP \u539f\u5219\u3002\u4e3a\u4e86\u4fee\u6539\u6b64\u7ed3\u6784\uff0c\u6709\u5fc5\u8981\u5b9a\u4e49\u66f4\u5c0f\u3001\u66f4\u5408\u9002\u7684\u63a5\u53e3\u3002\u56e0\u6b64\uff0c\u53ef\u4ee5\u8003\u8651\u4ee5\u4e0b\u63a5\u53e3\uff1a<\/p>\n<pre><code>public interface IBaseWorker\n{\n  public string Name { get; set; }\n  int CalculateSalary();\n}\n\npublic interface IFullTimeWorker : IBaseWorker\n{\n  public int MonthlySalary { get; set; }\n}\n\npublic interface IPartTimeWorker : IBaseWorker\n{\n  public int HourlySalary { get; set; }\n  public int HoursInMonth { get; set; }\n}<\/code><\/pre>\n<p>Then the FullTimeWorker and PartTimeWorker classes can be implemented as follows:<br \/>\n\u7136\u540e\uff0c\u53ef\u4ee5\u6309\u5982\u4e0b\u65b9\u5f0f\u5b9e\u73b0 FullTimeWorker \u548c PartTimeWorker \u7c7b\uff1a<\/p>\n<pre><code>public class FullTimeWorke : IFullTimeWorker\n{\n  public string Name { get; set; }\n  public int MonthlySalary { get; set; }\n  public int CalculateSalary()=&gt;MonthlySalary+(MonthlySalary * 10 \/ 100);\n}\n\npublic class PartTimeWorker : IPartTimeWorker\n{\n  public string Name { get; set; }\n  public int HourlySalary { get; set; }\n  public int HoursInMonth { get; set; }\n  public int CalculateSalary() =&gt; HourlySalary * HoursInMonth;\n}<\/code><\/pre>\n<p>Now, the FullTimeWorker class has implemented the IFullTimeWorker interface. It does not need to provide its implementation for the HourlySalary and HoursInMonth features. The same condition is true for PartTimeWorker class and IPartTimeWorker interface. Therefore, with these changes, the ISP principle has been observed.<\/p>\n<p>\u73b0\u5728\uff0cFullTimeWorker \u7c7b\u5df2\u7ecf\u5b9e\u73b0\u4e86 IFullTimeWorker \u63a5\u53e3\u3002\u5b83\u4e0d\u9700\u8981\u63d0\u4f9b HourlySalary \u548c HoursInMonth \u529f\u80fd\u7684\u5b9e\u73b0\u3002\u5bf9\u4e8e PartTimeWorker \u7c7b\u548c IPartTimeWorker \u63a5\u53e3\uff0c\u60c5\u51b5\u76f8\u540c\u3002\u56e0\u6b64\uff0c\u901a\u8fc7\u8fd9\u4e9b\u66f4\u6539\uff0c\u5df2\u7ecf\u9075\u5b88\u4e86 ISP \u539f\u5219\u3002<\/p>\n<h4>Dependency Inversion Principle<\/h4>\n<h4>\u4f9d\u8d56\u5173\u7cfb\u53cd\u8f6c\u539f\u5219<\/h4>\n<p>This principle states that high-level modules and classes should not depend on low-level modules and classes. In other words, a high-level module should not contain anything from a low-level module, and the bridge between these two modules should only be formed through abstractions. These abstractions should not be dependent on the details, and the details themselves should be dependent on the abstractions. In this way, the code written will be easily expandable and maintainable. For example, consider the following code:<br \/>\n\u8be5\u539f\u5219\u6307\u51fa\uff0c\u9ad8\u7ea7\u6a21\u5757\u548c\u7c7b\u4e0d\u5e94\u4f9d\u8d56\u4e8e\u4f4e\u7ea7\u6a21\u5757\u548c\u7c7b\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u9ad8\u7ea7\u6a21\u5757\u4e0d\u5e94\u5305\u542b\u6765\u81ea\u4f4e\u7ea7\u6a21\u5757\u7684\u4efb\u4f55\u5185\u5bb9\uff0c\u5e76\u4e14\u8fd9\u4e24\u4e2a\u6a21\u5757\u4e4b\u95f4\u7684\u6865\u6881\u53ea\u80fd\u901a\u8fc7\u62bd\u8c61\u5f62\u6210\u3002\u8fd9\u4e9b\u62bd\u8c61\u4e0d\u5e94\u8be5\u4f9d\u8d56\u4e8e\u7ec6\u8282\uff0c\u7ec6\u8282\u672c\u8eab\u5e94\u8be5\u4f9d\u8d56\u4e8e\u62bd\u8c61\u3002\u8fd9\u6837\uff0c\u7f16\u5199\u7684\u4ee3\u7801\u5c06\u6613\u4e8e\u6269\u5c55\u548c\u7ef4\u62a4\u3002\u4f8b\u5982\uff0c\u8bf7\u8003\u8651\u4ee5\u4e0b\u4ee3\u7801\uff1a<\/p>\n<pre><code>public class User\n{\n  public string FirstName { get; set; }\n  public string Email { get; set; }\n  public static List&lt;User&gt; Users { get; set; } = new List&lt;User&gt;();\n  public void NewUser(User user)\n  {\n    Users.Add(user);\n    new EmailService()\n    .SendEmail(user.Email,&quot;Account Created&quot;,&quot;Your new account created&quot;);\n  }\n}\n\npublic class EmailService\n{\n  public void SendEmail(string email, string subject, string body)\n  {\n    \/\/Send email\n  }\n}<\/code><\/pre>\n<p>In the preceding code, the high-level class User is dependent on the low-level class EmailService, and therefore the maintenance and development of this code always need help. With these specifications, DIP still needs to be met. In order to comply with DIP, the preceding code can be rewritten as the following:<\/p>\n<p>\u5728\u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\uff0c\u9ad8\u7ea7\u7c7b User \u4f9d\u8d56\u4e8e\u4f4e\u7ea7\u7c7b EmailService\uff0c\u56e0\u6b64\u6b64\u4ee3\u7801\u7684\u7ef4\u62a4\u548c\u5f00\u53d1\u59cb\u7ec8\u9700\u8981\u5e2e\u52a9\u3002\u5bf9\u4e8e\u8fd9\u4e9b\u89c4\u8303\uff0c\u4ecd\u7136\u9700\u8981\u6ee1\u8db3 DIP\u3002\u4e3a\u4e86\u7b26\u5408 DIP\uff0c\u53ef\u4ee5\u5c06\u4e0a\u8ff0\u4ee3\u7801\u91cd\u5199\u4e3a\u4ee5\u4e0b\u5185\u5bb9\uff1a<\/p>\n<pre><code>public class User\n{\n  private readonly IEmailService _emailService;\n  public string FirstName { get; set; }\n  public string Email { get; set; }\n  public static List&lt;User&gt; Users { get; set; } = new List&lt;User&gt;();\n  public User(IEmailService emailService)=&gt;this._emailService=emailService;\n  public void NewUser(User user)\n  {\n    Users.Add(user);\n    _emailService\n    .SendEmail(user.Email,&quot;Account Created&quot;,&quot;Your new account created&quot;);\n  }\n}\n\npublic interface IEmailService\n{\n  void SendEmail(string email, string subject, string body);\n}\n\npublic class EmailService : IEmailService\n{\n  public void SendEmail(string email, string subject, string body)\n  {\n    \/\/Send email\n  }\n}<\/code><\/pre>\n<p>In the preceding code, the User class is dependent on the IEmailService interface, and the EmailService class has also implemented this interface. In this way, while complying with DIP, code maintenance and development are improved.<br \/>\n\u5728\u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\uff0cUser \u7c7b\u4f9d\u8d56\u4e8e IEmailService \u63a5\u53e3\uff0c\u5e76\u4e14 EmailService \u7c7b\u4e5f\u5b9e\u73b0\u4e86\u6b64\u63a5\u53e3\u3002\u8fd9\u6837\uff0c\u5728\u9075\u5b88 DIP \u7684\u540c\u65f6\uff0c\u4ee3\u7801\u7ef4\u62a4\u548c\u5f00\u53d1\u5f97\u5230\u4e86\u6539\u8fdb\u3002<\/p>\n<h2>UML class diagram<\/h2>\n<h2>UML \u7c7b\u56fe<\/h2>\n<p>UML is a standard modeling language that consists of a set of diagrams. These diagrams help software developers to define software requirements, depict them and document them after construction. The diagrams in UML not only help software engineers during the software production process but also allow business owners and analysts to understand and model their needs more accurately.<\/p>\n<p>UML \u662f\u4e00\u79cd\u7531\u4e00\u7ec4\u56fe\u7ec4\u6210\u7684\u6807\u51c6\u5efa\u6a21\u8bed\u8a00\u3002\u8fd9\u4e9b\u56fe\u8868\u53ef\u5e2e\u52a9\u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u5b9a\u4e49\u8f6f\u4ef6\u9700\u6c42\u3001\u63cf\u8ff0\u5b83\u4eec\u5e76\u5728\u6784\u5efa\u540e\u8bb0\u5f55\u5b83\u4eec\u3002UML \u4e2d\u7684\u56fe\u8868\u4e0d\u4ec5\u53ef\u4ee5\u5728\u8f6f\u4ef6\u751f\u4ea7\u8fc7\u7a0b\u4e2d\u5e2e\u52a9\u8f6f\u4ef6\u5de5\u7a0b\u5e08\uff0c\u8fd8\u53ef\u4ee5\u8ba9\u4f01\u4e1a\u4e3b\u548c\u5206\u6790\u5e08\u66f4\u51c6\u786e\u5730\u7406\u89e3\u548c\u5efa\u6a21\u4ed6\u4eec\u7684\u9700\u6c42\u3002<\/p>\n<p>UML is very important in the development of object-oriented software, and for this, UML uses a series of graphical symbols. With the help of modeling UML, team members can talk about design and architecture with better and more accuracy and fix possible defects.<\/p>\n<p>UML \u5728\u9762\u5411\u5bf9\u8c61\u8f6f\u4ef6\u7684\u5f00\u53d1\u4e2d\u975e\u5e38\u91cd\u8981\uff0c\u4e3a\u6b64\uff0cUML \u4f7f\u7528\u4e00\u7cfb\u5217\u56fe\u5f62\u7b26\u53f7\u3002\u5728\u5efa\u6a21 UML \u7684\u5e2e\u52a9\u4e0b\uff0c\u56e2\u961f\u6210\u5458\u53ef\u4ee5\u66f4\u597d\u3001\u66f4\u51c6\u786e\u5730\u8ba8\u8bba\u8bbe\u8ba1\u548c\u67b6\u6784\uff0c\u5e76\u4fee\u590d\u53ef\u80fd\u7684\u7f3a\u9677\u3002<\/p>\n<p>During the past years, UML has undergone various changes, which can be followed in the figure:<\/p>\n<p>\u5728\u8fc7\u53bb\u7684\u51e0\u5e74\u91cc\uff0cUML \u53d1\u751f\u4e86\u5404\u79cd\u53d8\u5316\uff0c\u5982\u56fe\u6240\u793a\uff1a<\/p>\n<p><img decoding=\"async\" src=\"\/net7designpatternsindepth\/0111.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 1.11: UML versions<br \/>\n\u56fe 1.11. UML \u7248\u672c<\/p>\n<p>When UML is examined and studied, various diagrams can be seen. The reason for this diversity is that different people participate in the production process, and each person sees the product from a different angle according to their role in the team. For example, the use that a programmer makes of UML diagrams is very different from the use made by an analyst.<\/p>\n<p>\u5f53\u68c0\u67e5\u548c\u7814\u7a76 UML \u65f6\uff0c\u53ef\u4ee5\u770b\u5230\u5404\u79cd\u56fe\u8868\u3002\u8fd9\u79cd\u591a\u6837\u6027\u7684\u539f\u56e0\u662f\u4e0d\u540c\u7684\u4eba\u53c2\u4e0e\u751f\u4ea7\u8fc7\u7a0b\uff0c\u6bcf\u4e2a\u4eba\u6839\u636e\u4ed6\u4eec\u5728\u56e2\u961f\u4e2d\u7684\u89d2\u8272\u4ece\u4e0d\u540c\u7684\u89d2\u5ea6\u770b\u5f85\u4ea7\u54c1\u3002\u4f8b\u5982\uff0c\u7a0b\u5e8f\u5458\u5bf9 UML \u56fe\u7684\u4f7f\u7528\u4e0e\u5206\u6790\u5e08\u5bf9 UML \u56fe\u7684\u4f7f\u7528\u975e\u5e38\u4e0d\u540c\u3002<\/p>\n<p>In a general classification, UML diagrams can be divided into two main categories:<br \/>\n\u5728\u4e00\u822c\u5206\u7c7b\u4e2d\uff0cUML \u56fe\u53ef\u4ee5\u5206\u4e3a\u4e24\u5927\u7c7b\uff1a<\/p>\n<ol>\n<li>Structural diagrams: These diagrams show the static structure of the system along with different levels of abstraction and implementation and their relationship with each other. The following 7 are structural diagrams in UML:<br \/>\n\u7ed3\u6784\u56fe\uff1a\u8fd9\u4e9b\u56fe\u663e\u793a\u4e86\u7cfb\u7edf\u7684\u9759\u6001\u7ed3\u6784\u4ee5\u53ca\u4e0d\u540c\u7ea7\u522b\u7684\u62bd\u8c61\u548c\u5b9e\u73b0\u4ee5\u53ca\u5b83\u4eec\u4e4b\u95f4\u7684\u5173\u7cfb\u3002\u4ee5\u4e0b 7 \u4e2a\u662f UML \u4e2d\u7684\u7ed3\u6784\u56fe\uff1a<\/li>\n<\/ol>\n<ul>\n<li>Class Diagram \u7c7b\u56fe<\/li>\n<li>Component Diagram \u7ec4\u4ef6\u56fe<\/li>\n<li>Deployment Diagram \u90e8\u7f72\u56fe<\/li>\n<li>Object Diagram \u5bf9\u8c61\u56fe<\/li>\n<li>Package Diagram \u6253\u5305\u56fe <\/li>\n<li>Composite Structure Diagram \u590d\u5408\u7ed3\u6784\u56fe<\/li>\n<li>Profile Diagram \u8f6e\u5ed3\u56fe<\/li>\n<\/ul>\n<ol start=\"2\">\n<li>Behavioral diagrams: These diagrams show the dynamic behavior of objects in the system. This dynamic behavior can usually be displayed in the form of a series of changes over time. Types of behavioral charts are as follows:<br \/>\n\u884c\u4e3a\u56fe\uff1a \u8fd9\u4e9b\u56fe\u663e\u793a\u4e86\u7cfb\u7edf\u4e2d\u5bf9\u8c61\u7684\u52a8\u6001\u884c\u4e3a\u3002\u8fd9\u79cd\u52a8\u6001\u884c\u4e3a\u901a\u5e38\u53ef\u4ee5\u968f\u65f6\u95f4\u63a8\u79fb\u7684\u4e00\u7cfb\u5217\u53d8\u5316\u7684\u5f62\u5f0f\u663e\u793a\u3002\u884c\u4e3a\u56fe\u7684\u7c7b\u578b\u5982\u4e0b\uff1a<\/li>\n<\/ol>\n<ul>\n<li>Use Case Diagram \u7528\u4f8b\u56fe<\/li>\n<li>Activity Diagram \u6d3b\u52a8\u56fe<\/li>\n<li>State Machine Diagram \u72b6\u6001\u673a \u56fe<\/li>\n<li>Sequence Diagram \u5e8f\u5217\u56fe<\/li>\n<li>Communication Diagram \u901a\u4fe1\u56fe<\/li>\n<li>Interaction Overview Diagram \u4ea4\u4e92\u6982\u8ff0 \u56fe<\/li>\n<li>Timing Diagram \u65f6\u5e8f\u56fe<\/li>\n<\/ul>\n<h4>Class diagram<\/h4>\n<h4>\u7c7b\u56fe<\/h4>\n<p>This diagram is one of the most popular and widely used UML diagrams. The class diagram describes the different types in the system and the static relationships between them. Also, with the help of this diagram, you can see the characteristics and behaviors of each class and even define limits on the relationship between classes. The following figure shows a class in a class diagram:<br \/>\n\u8be5\u56fe\u662f\u6700\u6d41\u884c\u548c\u6700\u5e7f\u6cdb\u4f7f\u7528\u7684 UML \u56fe\u4e4b\u4e00\u3002\u7c7b\u56fe\u63cf\u8ff0\u4e86\u7cfb\u7edf\u4e2d\u7684\u4e0d\u540c\u7c7b\u578b\u4ee5\u53ca\u5b83\u4eec\u4e4b\u95f4\u7684\u9759\u6001\u5173\u7cfb\u3002\u6b64\u5916\uff0c\u501f\u52a9\u6b64\u56fe\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u6bcf\u4e2a\u7c7b\u7684\u7279\u5f81\u548c\u884c\u4e3a\uff0c\u751a\u81f3\u53ef\u4ee5\u5b9a\u4e49\u7c7b\u4e4b\u95f4\u5173\u7cfb\u7684\u9650\u5236\u3002\u4e0b\u56fe\u663e\u793a\u4e86\u7c7b\u56fe\u4e2d\u7684\u4e00\u4e2a\u7c7b\uff1a<\/p>\n<p><img decoding=\"async\" src=\"\/net7designpatternsindepth\/0112.png\" alt=\"alt text\" \/><br \/>\nFigure 1 12: Class in a Class Diagram<br \/>\n\u56fe 12\uff1a\u7c7b\u56fe\u4e2d\u7684\u7c7b<\/p>\n<p>As you can see, each class has a name (Class Name), some characteristics, and behaviors. Properties are given in the upper part of the class (prop1 and prop2). Behaviors are also given in the lower part (op1 and op2).<br \/>\n\u5982\u60a8\u6240\u89c1\uff0c\u6bcf\u4e2a\u7c7b\u90fd\u6709\u4e00\u4e2a\u540d\u79f0 \uff08Class Name\uff09\u3001\u4e00\u4e9b\u7279\u5f81\u548c\u884c\u4e3a\u3002\u5c5e\u6027\u5728\u7c7b\u7684\u4e0a\u534a\u90e8\u5206\uff08prop1 \u548c prop2\uff09\u4e2d\u7ed9\u51fa\u3002\u4e0b\u534a\u90e8\u5206\u8fd8\u7ed9\u51fa\u4e86\u884c\u4e3a \uff08op1 \u548c op2\uff09\u3002<\/p>\n<p>Characteristics in the class diagram are divided into two categories:<br \/>\n\u7c7b\u56fe\u4e2d\u7684\u7279\u5f81\u5206\u4e3a\u4e24\u7c7b\uff1a<\/p>\n<ul>\n<li>\n<p>Attributes: This indicator presents the attribute in the form of a written text within the class, which is in the following format. In this format, only a name is required.<br \/>\nAttributes\uff1a\u6b64\u6307\u6807\u5728\u7c7b\u4e2d\u4ee5\u4e66\u9762\u6587\u672c\u7684\u5f62\u5f0f\u5448\u73b0\u5c5e\u6027\uff0c\u683c\u5f0f\u5982\u4e0b\u3002\u5728\u6b64\u683c\u5f0f\u4e2d\uff0c\u53ea\u9700\u8981\u540d\u79f0\u3002<br \/>\nvisibility name : type multiplicity = default {property-string}<br \/>\nFor example, in the preceding class, the property called prop1 is defined. The access level of this property is private, and its type is an array of int.<br \/>\n\u4f8b\u5982\uff0c\u5728\u524d\u9762\u7684\u7c7b\u4e2d\uff0c\u5b9a\u4e49\u4e86\u540d\u4e3a prop1 \u7684\u5c5e\u6027\u3002\u6b64\u5c5e\u6027\u7684\u8bbf\u95ee\u7ea7\u522b\u4e3a private\uff0c\u5176\u7c7b\u578b\u4e3a int \u6570\u7ec4\u3002<\/p>\n<\/li>\n<li>\n<p>Relationships: Another way to display features is to use the relationship indicator. Using this indicator, two classes are connected through a line. Relationships can be one-way or two-way.<br \/>\n\u5173\u7cfb\uff1a\u663e\u793a\u7279\u5f81\u7684\u53e6\u4e00\u79cd\u65b9\u6cd5\u662f\u4f7f\u7528\u5173\u7cfb\u6307\u793a\u5668\u3002\u4f7f\u7528\u6b64\u6307\u6807\uff0c\u4e24\u4e2a\u7c7b\u901a\u8fc7\u4e00\u6761\u7ebf\u8fde\u63a5\u3002\u5173\u7cfb\u53ef\u4ee5\u662f\u5355\u5411\u7684\uff0c\u4e5f\u53ef\u4ee5\u662f\u53cc\u5411\u7684\u3002<br \/>\nBehaviors are things that an object of the class should be able to do. The methods can be displayed in the following format in the class diagram:<br \/>\n\u884c\u4e3a\u662f\u7c7b\u7684\u5bf9\u8c61\u5e94\u8be5\u80fd\u591f\u6267\u884c\u7684\u4f5c\u3002\u8fd9\u4e9b\u65b9\u6cd5\u53ef\u4ee5\u5728\u7c7b\u56fe\u4e2d\u6309\u4ee5\u4e0b\u683c\u5f0f\u663e\u793a\uff1a<br \/>\nvisibility name (parameter-list): return-type {property-string}<br \/>\nFor example, in the preceding class diagram, a method named op1 is defined with a public access level. Whose return type is Boolean. Also, an input parameter called param1 is defined for the op2 method.<br \/>\n\u4f8b\u5982\uff0c\u5728\u524d\u9762\u7684\u7c7b\u56fe\u4e2d\uff0c\u540d\u4e3a op1 \u7684\u65b9\u6cd5\u5b9a\u4e49\u4e86\u4e00\u4e2a public \u8bbf\u95ee\u7ea7\u522b\u3002\u5176\u8fd4\u56de\u7c7b\u578b\u4e3a Boolean\u3002\u6b64\u5916\uff0c\u8fd8\u4e3a op2 \u65b9\u6cd5\u5b9a\u4e49\u4e86\u4e00\u4e2a\u540d\u4e3a param1 \u7684\u8f93\u5165\u53c2\u6570\u3002<\/p>\n<\/li>\n<\/ul>\n<p>Each class diagram usually consists of several classes or interfaces and connections between them. There may be an inheritance relationship between classes. To show this type of relationship, Generalization is used:<br \/>\n\u6bcf\u4e2a\u7c7b\u56fe\u901a\u5e38\u7531\u591a\u4e2a\u7c7b\u6216\u63a5\u53e3\u4ee5\u53ca\u5b83\u4eec\u4e4b\u95f4\u7684\u8fde\u63a5\u7ec4\u6210\u3002\u7c7b\u4e4b\u95f4\u53ef\u80fd\u5b58\u5728\u7ee7\u627f\u5173\u7cfb\u3002\u4e3a\u4e86\u663e\u793a\u8fd9\u79cd\u7c7b\u578b\u7684\u5173\u7cfb\uff0c\u4f7f\u7528\u4e86\u6cdb\u5316\uff1a<\/p>\n<p><img decoding=\"async\" src=\"\/net7designpatternsindepth\/0113.png\" alt=\"alt text\" \/><br \/>\nFigure 1.13: Generalization in Class Diagram<br \/>\n\u56fe 1.13.. \u7c7b\u56fe\u4e2d\u7684\u6cdb\u5316<\/p>\n<p>For example, the preceding diagram shows that Class2 inherits from Class1, so all the features and behaviors available to Class1 are also available to Class2.<br \/>\n\u4f8b\u5982\uff0c\u4e0a\u56fe\u663e\u793a Class2 \u7ee7\u627f\u81ea Class1\uff0c\u56e0\u6b64 Class1 \u53ef\u7528\u7684\u6240\u6709\u529f\u80fd\u548c\u884c\u4e3a\u4e5f\u53ef\u7528\u4e8e Class2\u3002<\/p>\n<p>For another example, a class may use or depend on another class. To display this type of relationship, Dependency must be used. In this type of relationship, changes on the supplier side usually lead to changes on the client side. Classes can depend on each other for different reasons and types. One of the most used dependencies, which has been used many times in this chapter, is use:<br \/>\n\u518d\u4e3e\u4e00\u4e2a\u4f8b\u5b50\uff0c\u4e00\u4e2a\u7c7b\u53ef\u80fd\u4f7f\u7528\u6216\u4f9d\u8d56\u4e8e\u53e6\u4e00\u4e2a\u7c7b\u3002\u8981\u663e\u793a\u8fd9\u79cd\u7c7b\u578b\u7684\u5173\u7cfb\uff0c\u5fc5\u987b\u4f7f\u7528 Dependency \u3002\u5728\u8fd9\u79cd\u7c7b\u578b\u7684\u5173\u7cfb\u4e2d\uff0c\u4f9b\u5e94\u5546\u7aef\u7684\u53d8\u5316\u901a\u5e38\u4f1a\u5bfc\u81f4\u5ba2\u6237\u7aef\u7684\u53d8\u5316\u3002\u7c7b\u53ef\u4ee5\u7531\u4e8e\u4e0d\u540c\u7684\u539f\u56e0\u548c\u7c7b\u578b\u800c\u76f8\u4e92\u4f9d\u8d56\u3002\u6700\u5e38\u7528\u7684\u4f9d\u8d56\u9879\u4e4b\u4e00\u662f use\uff1a<\/p>\n<p><img decoding=\"async\" src=\"\/net7designpatternsindepth\/0114.png\" alt=\"alt text\" \/><br \/>\nFigure 1.14: Use relation in Class Diagram<br \/>\n\u56fe 1.14.. \u5728\u7c7b\u56fe\u4e2d\u4f7f\u7528\u5173\u7cfb<\/p>\n<p>In the preceding figure, Class2 has the role of Supplier, and Class1 has the role of Client. According to the preceding diagram, Class1 is dependent on Class2 through the use of dependency. In other words, Class1 uses Class2.<br \/>\n\u5728\u4e0a\u56fe\u4e2d\uff0cClass2 \u5177\u6709 Supplier \u89d2\u8272\uff0cClass1 \u5177\u6709 Client \u89d2\u8272\u3002\u6839\u636e\u4e0a\u56fe\uff0cClass1 \u901a\u8fc7\u4f7f\u7528\u4f9d\u8d56\u5173\u7cfb\u4f9d\u8d56\u4e8e Class2\u3002\u6362\u53e5\u8bdd\u8bf4\uff0cClass1 \u4f7f\u7528 Class2\u3002<\/p>\n<p>During software development, apart from inherent classes, we may also deal with abstract classes or interfaces:<br \/>\n\u5728\u8f6f\u4ef6\u5f00\u53d1\u8fc7\u7a0b\u4e2d\uff0c\u9664\u4e86\u56fa\u6709\u7684\u7c7b\uff0c\u6211\u4eec\u8fd8\u53ef\u4ee5\u5904\u7406\u62bd\u8c61\u7c7b\u6216\u63a5\u53e3\uff1a<\/p>\n<p><img decoding=\"async\" src=\"\/net7designpatternsindepth\/0115.png\" alt=\"alt text\" \/><br \/>\nFigure 1.15: Abstract classes and interfaces in Class Diagram<br \/>\n\u56fe 1.15.. \u7c7b\u56fe\u4e2d\u7684\u62bd\u8c61\u7c7b\u548c\u63a5\u53e3<\/p>\n<p>In the preceding diagram, there is an inherent class called Class1, which inherits from the AbstractClass. The name of the abstract class is written in italics. Also, Class1 has implemented the IClass interface. Visually, it is very easy to recognize the interface.<\/p>\n<p>\u5728\u4e0a\u56fe\u4e2d\uff0c\u6709\u4e00\u4e2a\u540d\u4e3a Class1 \u7684\u56fa\u6709\u7c7b\uff0c\u5b83\u7ee7\u627f\u81ea AbstractClass\u3002\u62bd\u8c61\u7c7b\u7684\u540d\u79f0\u4ee5\u659c\u4f53\u4e66\u5199\u3002\u6b64\u5916\uff0cClass1 \u8fd8\u5b9e\u73b0\u4e86 IClass \u63a5\u53e3\u3002\u4ece\u89c6\u89c9\u4e0a\u770b\uff0c\u5f88\u5bb9\u6613\u8bc6\u522b\u754c\u9762\u3002<\/p>\n<h2>Conclusion<\/h2>\n<h2>\u7ed3\u675f\u8bed<\/h2>\n<p>In this chapter, software architecture and design patterns, the .NET framework, and UML were introduced in general. According to the points mentioned in this chapter, it should be possible to identify good architectural factors and produce software in accordance with some important programming principles.<\/p>\n<p>\u5728\u672c\u7ae0\u4e2d\uff0c\u4e00\u822c\u4ecb\u7ecd\u4e86\u8f6f\u4ef6\u4f53\u7cfb\u7ed3\u6784\u548c\u8bbe\u8ba1\u6a21\u5f0f\u3001.NET \u6846\u67b6\u548c UML\u3002\u6839\u636e\u672c\u7ae0\u4e2d\u63d0\u5230\u7684\u8981\u70b9\uff0c\u5e94\u8be5\u80fd\u591f\u8bc6\u522b\u51fa\u597d\u7684\u67b6\u6784\u56e0\u7d20\uff0c\u5e76\u6839\u636e\u4e00\u4e9b\u91cd\u8981\u7684\u7f16\u7a0b\u539f\u5219\u6765\u751f\u4ea7\u8f6f\u4ef6\u3002<\/p>\n<p>In the next chapter, the first category of GoF design patterns (Creational design patterns) will be introduced and examined, and it will be investigated how to manage the object initialization according to different creational design patterns.<\/p>\n<p>\u5728\u4e0b\u4e00\u7ae0\u4e2d\uff0c\u5c06\u4ecb\u7ecd\u548c\u7814\u7a76 GoF \u8bbe\u8ba1\u6a21\u5f0f\u7684\u7b2c\u4e00\u7c7b\uff08Creational Design patterns\uff09\uff0c\u5e76\u7814\u7a76\u5982\u4f55\u6839\u636e\u4e0d\u540c\u7684\u521b\u5efa\u8bbe\u8ba1\u6a21\u5f0f\u7ba1\u7406\u5bf9\u8c61\u521d\u59cb\u5316\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Chapter 1 Introduction to Design Patterns Introduction \u7b80\u4ecb One of the problems in understanding and using design patterns is the need for proper insight into software architecture and the reason for using design patterns. When this insight does not exist, design patterns will increase complexity. As they are not used in their proper place, the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[21],"class_list":["post-691","post","type-post","status-publish","format-standard","hentry","category-csharp","tag-net-7-design-patterns-in-depth"],"_links":{"self":[{"href":"https:\/\/diji.net\/index.php?rest_route=\/wp\/v2\/posts\/691","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/diji.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/diji.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/diji.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/diji.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=691"}],"version-history":[{"count":0,"href":"https:\/\/diji.net\/index.php?rest_route=\/wp\/v2\/posts\/691\/revisions"}],"wp:attachment":[{"href":"https:\/\/diji.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=691"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/diji.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=691"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/diji.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=691"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}