提交 cab3ad84 编写于 作者: W wizardforcel

2020-06-14 16:02:40

上级 9524c856
......@@ -53,7 +53,7 @@ Summary
更重要的是,如果我想在应用中添加更多社交平台,则应用代码应在不破坏设计的情况下容纳它。
## 具有策略设计模式的解决方案
## 使用策略设计模式的解决方案
在上述问题中,我们有一个可以以多种方式(连接到朋友)完成的操作,用户可以在运行时选择所需的方式。 因此,它非常适合用于策略设计模式。
......@@ -235,7 +235,7 @@ Connecting with Lokesh through GooglePlus
Connecting with Lokesh through Orkut [not possible though :)]
```
## 热门实现
## 流行实现
1. Java `Collections.sort(list, comparator)`方法,客户端根据运行时的要求实际将适当的比较器传递给该方法,并且该方法通用以接受任何比较器类型。 根据传递的比较器,可以对同一集合进行不同的排序。
2. [Log4j](//howtodoinjava.com/log4j2/) 中的附加器,布局和过滤器。
......
......@@ -40,7 +40,7 @@ How to use visitors in application code
**`ConcreteVisitable`** – 这些类实现了 Visitable 接口或类并定义了接受操作。 使用 accept 操作将访问者对象传递给该对象。
## 要解决的样本问题
## 要解决的示例问题
一个例子总是比冗长的理论更好。 因此,让我们在这里也有一个访问者设计模式。
......
......@@ -65,7 +65,7 @@ Final notes
复合叶子还可以选择在叶子节点处理请求之前或之后修改请求/响应。
## 要解决的样本问题
## 要解决的示例问题
假设我们正在构建财务应用。 我们的客户拥有多个银行帐户。 我们被要求准备一个设计,该设计可用于生成客户的合并帐户视图,该视图能够在合并所有帐户对帐单后显示**客户的总帐户余额以及合并对帐单**。 因此,应用应该能够生成:
......
......@@ -11,13 +11,13 @@
* 当我们需要大量类似的对象时,这些对象只有几个参数是唯一的,而大多数东西通常都是通用的。
* 我们需要通过创建更少的对象并将它们共享来控制大量对象的内存消耗。
## 2.外和固有属性
## 2.外和固有属性
享元物体本质上具有两种属性 - 内部属性和外部属性。
**固有**状态属性存储/共享在享元对象中,并且与享元的上下文无关。 作为最佳实践,我们应该使固有状态[**不可变**](https://howtodoinjava.com/java/basics/how-to-make-a-java-class-immutable/)
**外**状态会随着重量级环境的变化而变化,这就是为什么它们无法共享的原因。 客户端对象保持外部状态,它们需要在对象创建过程中将其传递给享元对象。
**外**状态会随着重量级环境的变化而变化,这就是为什么它们无法共享的原因。 客户端对象保持外部状态,它们需要在对象创建过程中将其传递给享元对象。
![Flyweight Pattern](img/054ddc3572d6b01d2aa3efb30c3a0665.png)
......@@ -233,9 +233,9 @@ Drawing THICK content in color : BLUE
* 减少系统中“完整但相似的对象”的总数。
* 提供了集中机制来控制许多“虚拟”对象的状态。
#### 5.4 内在和外在数据可以共享吗?
#### 5.4 内部和外部数据可以共享吗?
数据是可共享的,因为它是所有上下文通用的。 不共享外部数据。 客户需要将信息(状态)传递给飞锤,这是其上下文所特有的。
数据是可共享的,因为它是所有上下文通用的。 不共享外部数据。 客户需要将信息(状态)传递给飞锤,这是其上下文所特有的。
#### 5.5 享元模式的挑战
......
......@@ -8,13 +8,13 @@
有两种流行的定义来描述这一原则:
#### 1.1 迈耶的定义
#### 1.1 Mayer 的定义
伯特兰·梅耶(Bertrand Mayer)在其 1988 年的著作面向对象的软件构造(Prentice Hall)中,定义了开闭原则(OCP)如下:
> 软件实体应为扩展而开放,但应为修改而封闭。
#### 1.2 迈耶的定义
#### 1.2 Martin 的定义
Robert C. Martin 在他的书《敏捷软件开发:原则,模式和实践》(Prentice Hall,2003 年)中定义了 OCP,如下所示:
......
......@@ -62,7 +62,7 @@ public class EmployeeStore implements IEmployeeStore
而且总是有机会在修改期间,某些开发人员可以更改用于共享员工方法的获取/添加员工方法的逻辑。
#### 2.2 解决方案是 SRP 原则
#### 2.2 SRP 原则的解决方案
要解决此问题,我们必须退出电子邮件功能,以分离专门处理电子邮件相关功能的接口和类。 这样,我们可以确定其他功能不会受到影响。
......
......@@ -28,7 +28,7 @@
缓慢测试的主要原因之一是依赖关系,必须处理外部邪恶的必需品,例如数据库,文件和网络调用。 他们花费数千毫秒。 因此,要使套件快速运行,必须避免通过使用[模拟测试](https://howtodoinjava.com/library/mock-testing-using-powermock-with-junit-and-mockito/)创建这些依赖项。
#### 隔离
#### 隔离
**永远不要编写依赖于其他测试用例的测试**。 无论您如何精心设计它们,总会有误报的可能性。 更糟的是,您可能最终会花费更多的时间来确定链中的哪个测试导致了失败。
......@@ -38,7 +38,7 @@
[SOLID 类设计原则](//howtodoinjava.com/best-practices/5-class-design-principles-solid-in-java/)的单一责任原则(SRP)指出,类应该小而单一。 这也可以应用于您的测试。 如果您的一种测试方法可能由于多种原因而失败,请考虑将其拆分为单独的测试。
#### 可重复
#### 可重复
**可重复测试**每次运行都会产生相同的结果。 要完成可重复的测试,必须将它们与外部环境中的任何东西隔离开,而不是直接控制。 在这些情况下,请随意使用模拟对象。 它们就是为此目的而设计的。
......
......@@ -85,7 +85,7 @@ Summary
在每个单独的测试用例中测试所有配置设置仅证明了一件事:“ **您知道如何复制和粘贴**。”
#### 6.清一致地命名您的单元测试
#### 6.清一致地命名您的单元测试
好吧,这可能是最重要的一点,要记住并保持关注。 您必须根据测试案例的实际用途和测试来命名它们。 使用类名和方法名作为测试用例名称的测试用例命名约定从来都不是一个好主意。 每次更改方法名称或类名称时,您最终也会更新很多测试用例。
......@@ -100,7 +100,7 @@ Summary
4) TestCreateEmployee_ValidId_ShouldPass
```
#### 7.首先编写对依赖关系最少的方法的测试,然后逐步进行
#### 7.首先对依赖关系最少的方法编写测试,然后逐步进行
该原则表明,如果要测试`Employee`模块,则应该首先测试`Employee`模块的创建,因为它对外部测试用例的依赖项最小。 一旦完成,就开始编写`Employee`修改的测试用例,因为它们需要一些雇员在数据库中。
......@@ -110,7 +110,7 @@ Summary
好吧,这确实是有争议的。 您需要查找代码中最关键的部分,并且应该对其进行测试,而不必担心它们是否是私有的。 这些方法可以具有从一到两个类调用的某些关键算法,但是它们起着重要的作用。 您想确保它们按预期工作。
#### 9.针对每种单元测试方法,以精确地执行一个断言
#### 9.针对每种单元测试方法,精确执行一个断言
即使这不是经验法则,您也应该尝试在一个测试用例中仅测试一件事。 不要在单个测试用例中使用断言来测试多个事物。 这样,如果某个测试用例失败,则可以确切地知道出了什么问题。
......@@ -143,7 +143,7 @@ Summary
我们已经说过,每个测试用例都应该彼此独立,因此永远不需要静态数据成员。 但是,如果您在紧急情况下需要任何帮助,请记住在执行每个测试用例之前将其重新初始化为初始值。
#### 16.不要写自己的只能使测试失败的 catch
#### 16.不要写自己的只能使测试失败的`catch`
如果测试代码中的任何方法引发某些异常,则不要编写`catch`块只是为了捕获异常并使测试用例失败。 而是在测试用例声明本身中使用`throws Exception`语句。 我将建议使用`Exception`类,并且不要使用`Exception`的特定子类。 这也将增加测试范围。
......
......@@ -51,11 +51,11 @@ Test filling log files with load of texts
而是编写一个用于创建员工的肯定测试用例,并验证该单元测试中的所有字段。 在这种情况下,负测试用例应单独编写,仅做一件事和一个断言。 例如,一个测试用例用于空白的名字,一个测试用例用于无效的名字,依此类推。 可以使用单个断言来验证所有此类否定测试用例,这些断言可以期望[**响应中出现异常**](//howtodoinjava.com/junit/junit-testcases-which-expects-exception-on-runtime/ "Junit testcases which expects exception on runtime")
## 4)使用反射测试访问被测者
## 4)使用反射测试被测者的访问
这真是太糟糕了。 尝试将测试对象更改为需要的用户。 在测试对象上进行代码重构时会发生什么。 测试用例会爆炸。 请勿使用或允许使用。
## 5)测试被吞的异常
## 5)测试隐藏了异常
我得到了这些测试用例的应有份额。 在测试用例结束时,他们以小小的`catch`块静默地吞下了异常。 更糟糕的是,它们也不会发出失败的警报。 异常是您的应用抛出的信号,以表明发生了某些不良情况,您必须对其进行调查。 您不应允许测试用例忽略这些信号。
......@@ -79,11 +79,11 @@ Test filling log files with load of texts
另一种使其正确的方法是使用模拟对象。 他们在那里是为了这个目的。 是吗?
## 7)测试仅兼容显影机
## 7)测试仅兼容开发者的机器
这不是很广为人知,但当新生写的时候有时可见。 他们使用依赖于系统的文件路径,环境变量或属性来代替使用通用属性/路径或类似的东西。 提防他们。
## 8)使用文本加载测试填充日志文件
## 8)使用文本加载测试日志文件的填充
他们似乎并没有在快乐的日子里制造问题。 但是,在下雨天的时候,它们通过在日志文件中放置没有任何信息的不必要的文本来使人为难,并为试图查找那些日志文件中隐藏的内容的调试器带来了麻烦。
......
......@@ -44,11 +44,11 @@ Java 中的异常层次结构
#### 检查异常
#### 受检异常
这些是必须在方法的`throws`子句中声明的异常。 它们扩展了`Exception`,旨在成为“面对您”的异常类型。 Java 希望您处理它们,因为它们某种程度上取决于程序之外的外部因素。 受检的异常指示正常系统运行期间可能发生的预期问题。 通常,当您尝试通过网络或文件系统使用外部系统时,会发生这些异常。 通常,对检查到的异常的正确响应应该是稍后重试,或者提示用户修改其输入。
#### 非受检异常
#### 非受检异常
这些是不需要在`throws`子句中声明的异常。 JVM 不会强迫您处理它们,因为它们大多数是由于程序错误在运行时生成的。 它们扩展了`RuntimeException`。 最常见的示例是`NullPointerException`(很吓人。不是吗?)。 非受检的异常可能不应该重试,正确的操作通常应该是什么也不做,然后让它从方法中出来并通过执行栈。 在高级别执行时,应记录此类异常。
......@@ -92,7 +92,7 @@ catch (NoSuchMethodException e) {
这样做不仅返回“`null`”,而不是处理或重新引发异常,它完全吞没了异常,永远失去了错误原因。 而当您不知道失败的原因时,将来如何预防呢? 永远不要这样做!
#### 3.2 声明您的方法可以抛出的特定检查异常
#### 3.2 声明您的方法可以抛出的特定受检异常
```java
public void foo() throws Exception { //Incorrect way
......@@ -100,7 +100,7 @@ public void foo() throws Exception { //Incorrect way
```
始终避免像上面的代码示例中那样进行操作。 它根本无法达到检查异常的全部目的。 声明您的方法可以抛出的特定受检异常。 如果此类检查的异常太多,则可能应将它们包装在您自己的异常中,并在异常消息中添加信息。 如果可能,您还可以考虑代码重构。
始终避免像上面的代码示例中那样进行操作。 它根本无法达到受检异常的全部目的。 声明您的方法可以抛出的特定受检异常。 如果此类受检异常太多,则可能应将它们包装在您自己的异常中,并在异常消息中添加信息。 如果可能,您还可以考虑代码重构。
```java
public void foo() throws SpecificException1, SpecificException2 { //Correct way
......@@ -281,7 +281,7 @@ doSomethingCool();
```
#### 3.19 使用模板方法重复尝试捕获
#### 3.19 使用模板方法重复`try-catch`
在代码的 100 个地方没有使用相似的`catch`块是没有用的。 它增加了代码重复性,无济于事。 在这种情况下,请使用模板方法。
......
......@@ -106,7 +106,7 @@ Spring 提供了三种类型的依赖项注入:构造器注入,设置器注
> 阅读更多:[如何使 Java 类不可变](//howtodoinjava.com/java/related-concepts/how-to-make-a-java-class-immutable/ "How to make a java class immutable")
## 5)在构造器注入中将类型优先于索引以进行构造器参数匹配
## 5)在构造器注入中优先使用类型而不是索引以进行构造器参数匹配
最好避免使用构造器注入,而更偏向使用设置器注入进行依赖项注入。 但是,如果绝对需要使用构造器注入,则**总是更偏向基于类型而不是索引**的参数匹配。
......@@ -127,7 +127,7 @@ Spring 提供了三种类型的依赖项注入:构造器注入,设置器注
如您所见,基于类型的参数传递更具可读性,并且不易出错。 但是,只要基于类型的参数传递有任何歧义,就可以毫不犹豫地转到基于索引的参数传递。
## 6)在扩展形式上使用快捷方式形式
## 6)使用快捷形式而不是扩展形式
Spring bean 配置语义允许两种形式来指定属性值和其他 bean 引用。 一种是扩展形式,另一种是较短形式。 最好使用较短的版本。
......@@ -240,7 +240,7 @@ jdbc.password=password
在上面给出的示例中,容器将确保在应用初始化时间本身中设置数据源的所有属性/参数。
## 13)不要滥用/滥用依赖注入
## 13)不要滥用依赖注入
最后,请不要滥用引入[依赖注入](//howtodoinjava.com/spring/spring-core/inversion-of-control-ioc-and-dependency-injection-di-patterns-in-spring-framework-and-related-interview-questions/ "Inversion of control (IoC) and dependency injection (DI) patterns in spring framework and related interview questions")的动机。
......
......@@ -65,7 +65,7 @@ public class BubbleSortExample
Output: [3, 6, 10, 12, 13, 24, 70, 90]
```
## 冒泡排序性能和复杂
## 冒泡排序性能和复杂
1. 冒泡排序属于` O(n^2)`排序算法,这使得排序大型数据量效率很低。
2. 冒泡排序既是[**稳定的**](https://en.wikipedia.org/wiki/Sorting_algorithm#Stability),又是[**自适应的**](https://en.wikipedia.org/wiki/Adaptive_sort)
......
......@@ -4,7 +4,7 @@
如果字符串包含从 a 到 z 的所有字符,则认为该字符串是完整的。 给定一个字符串,检查它是否完整。 例如:
**样本输入**
**示例输入**
```java
3
......@@ -13,7 +13,7 @@ qwertyuioplkjhgfdsazxcvbnm
ejuxggfsts
```
**样本输出**
**示例输出**
```java
NO
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册