提交 3b466025 编写于 作者: W wizardforcel

2020-06-11 16:54:02

上级 feee09aa
......@@ -2,7 +2,7 @@
> 原文: [https://howtodoinjava.com/design-patterns/creational/abstract-factory-pattern-in-java/](https://howtodoinjava.com/design-patterns/creational/abstract-factory-pattern-in-java/)
**抽象工厂模式**是又一个[设计模式](//howtodoinjava.com/category/design-patterns/creational/ "creational design patterns"),并且被视为[工厂模式](//howtodoinjava.com/design-patterns/creational/implementing-factory-design-pattern-in-java/ "Implementing factory design pattern in java")的另一抽象层。 在本教程中,我们将扩展[工厂模式](//howtodoinjava.com/design-patterns/creational/implementing-factory-design-pattern-in-java/ "Implementing factory design pattern in java")中讨论的汽车工厂问题的范围。 我们将通过扩大汽车工厂的范围来学习何时使用工厂模式,然后通过抽象工厂模式解决扩展的范围。
**抽象工厂模式**是又一个[造型设计模式](//howtodoinjava.com/category/design-patterns/creational/ "creational design patterns"),并且被视为[工厂模式](//howtodoinjava.com/design-patterns/creational/implementing-factory-design-pattern-in-java/ "Implementing factory design pattern in java")的另一抽象层。 在本教程中,我们将扩展[工厂模式](//howtodoinjava.com/design-patterns/creational/implementing-factory-design-pattern-in-java/ "Implementing factory design pattern in java")中讨论的汽车工厂问题的范围。 我们将通过扩大汽车工厂的范围来学习何时使用工厂模式,然后通过抽象工厂模式解决扩展的范围。
```java
Table of Contents
......@@ -21,19 +21,19 @@ Table of Contents
为了描述抽象工厂模式,我们将考虑三种制造方式 - 所有其他国家/地区的*美国**亚洲**默认*。 支持多个位置将需要进行关键的设计更改。
首先,我们需要在问题说明中指定的每个**位置**中都有汽车制造厂。 即 *USACarFactory**AsiaCarFactory**DefaultCarFactory* 。 现在,我们的应用应该足够智能,可以识别使用的位置,因此我们应该能够使用适当的汽车工厂,甚至不知道内部将使用哪个汽车工厂实现。 这也可以避免我们为某个特定位置称呼错误的工厂。
首先,我们需要在问题说明中指定的每个**位置**中都有汽车工厂。 即`USACarFactory``AsiaCarFactory``DefaultCarFactory`。 现在,我们的应用应该足够智能,可以识别使用的位置,因此我们应该能够使用适当的汽车工厂,甚至不知道内部将使用哪个汽车工厂实现。 这也可以避免我们为某个特定位置称呼错误的工厂。
因此,基本上,我们需要另一层抽象,它将识别位置并在内部使用正确的汽车工厂实现方式,甚至不会向用户提供任何提示。 这正是使用抽象工厂模式来解决的问题。
## 2.基于抽象工厂模式的解决方案
#### 2.1 包
#### 2.1 包图
使用抽象工厂模式参与全局汽车工厂设计的类的类图。
![Abstract factory design pattern package diagram](img/539d4a4d7d62c886a580fcd475ecbefe.png "Abstract_factory_package_diagram")
#### 2.2 序图
#### 2.2 序图
此图显示了`CarFactory`工厂类背后的类与抽象之间的交互。
......@@ -41,7 +41,7 @@ Table of Contents
> 请注意,我已设计解决方案以完全隐藏最终用户的位置详细信息。 因此,我没有直接暴露任何特定于位置的工厂。
>
> 在替代解决方案中,我们可以首先基于 location 参数获取特定于位置的工厂,然后在抽象引用上使用其`buildCar()`方法来构建实际的汽车实例。
> 在替代解决方案中,我们可以首先基于`location`参数获取特定于位置的工厂,然后在抽象引用上使用其`buildCar()`方法来构建实际的汽车实例。
## 3.抽象工厂模式实现
......@@ -194,7 +194,7 @@ public class USACarFactory
```
好吧,现在我们所有 3 个不同的汽车制造厂。 现在,我们必须抽象化访问这些工厂的方式。
好吧,现在我们所有 3 个不同的汽车厂。 现在,我们必须抽象化访问这些工厂的方式。
```java
public class CarFactory
......@@ -258,12 +258,12 @@ Model- LUXURY built in ASIA
## 4.总结
我们已经看到了[工厂模式](//howtodoinjava.com/design-patterns/creational/implementing-factory-design-pattern-in-java/ "Implementing factory design pattern in java")的用例场景,因此,每当需要**一组工厂**上的另一个抽象级别时,都应考虑使用*抽象工厂模式*。 工厂模式与抽象工厂模式之间可能只是**的区别。**
我们已经看到了[工厂模式](//howtodoinjava.com/design-patterns/creational/implementing-factory-design-pattern-in-java/ "Implementing factory design pattern in java")的用例场景,因此,每当需要**一组工厂**上的另一个抽象级别时,都应考虑使用*抽象工厂模式*。 工厂模式与抽象工厂模式之间可能只是**这些区别**
您已经可以更深入地研究 JDK 分发中的抽象工厂的不同*实时示例:*
您已经可以更深入地研究 JDK 分发中的抽象工厂的不同*实时示例*
* [DocumentBuilderFactory#newInstance()](https://docs.oracle.com/javase/6/docs/api/javax/xml/parsers/DocumentBuilderFactory.html#newInstance%28%29 "DocumentBuilderFactory newinstance")
* [TransformerFactory#newInstance()](https://docs.oracle.com/javase/6/docs/api/javax/xml/transform/TransformerFactory.html#newInstance%28%29 "TransformerFactory newInstance")
* [`DocumentBuilderFactory#newInstance()`](https://docs.oracle.com/javase/6/docs/api/javax/xml/parsers/DocumentBuilderFactory.html#newInstance%28%29 "DocumentBuilderFactory newinstance")
* [`TransformerFactory#newInstance()`](https://docs.oracle.com/javase/6/docs/api/javax/xml/transform/TransformerFactory.html#newInstance%28%29 "TransformerFactory newInstance")
还有其他类似的示例,但是需要对**抽象工厂设计模式**有所了解,这是您到目前为止必须已经掌握的。
......
> 原文: [https://howtodoinjava.com/design-patterns/behavioral/](https://howtodoinjava.com/design-patterns/behavioral/)
在软件工程中,行为设计模式是一种设计模式,用于标识对象之间的通用通信模式并实现这些模式。 通过这样做,这些模式增加了执行此通信的灵活性。
在软件工程中,行为设计模式是一种设计模式,用于标识对象之间的通用通信模式并实现这些模式。 通过这样做,这些模式增加了执行此通信的灵活性。
行为模式与对象之间的责任分配有关,或者与将行为封装在对象中并委托给它有关。
行为模式与对象之间的责任分配有关,或者与将行为封装在对象中并委托给它有关。
与创建和结构模式不同,创建和结构模式处理实例化过程以及对象和类的蓝图,此处的中心思想是集中于对象的互连方式。 总之,我们可以这样说:如果 Creational 是关于实例化的,而 Structural 是蓝图,那么 Behavioral 是对象之间关系的模式。
\ No newline at end of file
与创建和结构型模式不同,创建和结构型模式处理实例化过程以及对象和类的蓝图,此处的中心思想是集中于对象的互连方式。 总之,我们可以这样说:如果 Creational 是关于实例化的,而 Structural 是蓝图,那么 Behavioral 是对象之间关系的模式。
\ No newline at end of file
......@@ -2,7 +2,7 @@
> 原文: [https://howtodoinjava.com/design-patterns/behavioral/chain-of-responsibility-design-pattern/](https://howtodoinjava.com/design-patterns/behavioral/chain-of-responsibility-design-pattern/)
[责任链](https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern "Chain-of-responsibility_pattern")被称为行为模式。 这种模式的主要目的是避免将请求的发送方耦合到接收方,从而为多个对象提供了处理请求的机会。 GoF 定义的核心逻辑是:
[责任链](https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern "Chain-of-responsibility_pattern")被称为行为模式。 这种模式的主要目的是避免将请求的发送方耦合到接收方,从而为多个对象提供了处理请求的机会。 GoF 定义的核心逻辑是:
```java
"Gives more than one object an opportunity to handle a request by linking receiving objects together."
......
......@@ -21,7 +21,7 @@ Summary
## 介绍
在面向对象的编程中,命令模式是一种行为设计模式,其中一个对象用于[封装](//howtodoinjava.com/object-oriented/encapsulation-in-java-and-its-relation-with-abstraction/)执行动作,业务操作或触发事件所需的所有信息。 方法名称,接收方对象引用和方法参数值(如果有)。 该对象称为*命令*
在面向对象的编程中,命令模式是一种行为设计模式,其中一个对象用于[封装](//howtodoinjava.com/object-oriented/encapsulation-in-java-and-its-relation-with-abstraction/)执行动作,业务操作或触发事件所需的所有信息。 方法名称,接收方对象引用和方法参数值(如果有)。 该对象称为*命令*
类似的方法也适用于[责任链](//howtodoinjava.com/design-patterns/behavioral/chain-of-responsibility-design-pattern/)模式。 唯一的区别是命令中只有一个请求处理器,而在责任链中单个请求对象可以有许多处理器。
......@@ -380,7 +380,7 @@ Fan stopped..
## 总结
1. 命令模式是一种行为设计模式。
1. 命令模式是一种行为设计模式。
2. 在命令模式中,对象用于封装在任何时间执行操作或触发事件所需的所有信息,从而使开发人员能够分散业务逻辑。 它称为命令。
3. 客户端与调用程序对话并传递命令对象。
4. 每个命令对象都有对其接收者的引用。
......
......@@ -4,7 +4,7 @@
根据 GoF 定义,**中介器模式**定义了一个对象,[封装了](https://howtodoinjava.com/oops/encapsulation-in-java-and-its-relation-with-abstraction/)一组对象如何交互。 中介者通过防止对象之间显式地相互引用来促进松散耦合,并且它使我们可以独立地更改其交互。
中介者是**行为设计模式**,也是 GoF 讨论的[其他 23 个模式](https://howtodoinjava.com/gang-of-four-java-design-patterns/)之一。
中介者是**行为设计模式**,也是 GoF 讨论的[其他 23 个模式](https://howtodoinjava.com/gang-of-four-java-design-patterns/)之一。
## 1.何时使用调解器设计模式
......
......@@ -2,7 +2,7 @@
> 原文: [https://howtodoinjava.com/design-patterns/behavioral/memento-design-pattern/](https://howtodoinjava.com/design-patterns/behavioral/memento-design-pattern/)
Memento 设计模式是行为模式,是 Gang of Four 讨论的 23 种[设计模式](https://howtodoinjava.com/gang-of-four-java-design-patterns/)之一。 **纪念图案**用于将对象的状态恢复到先前的状态。 也称为**快照模式**
Memento 设计模式是行为模式,是 Gang of Four 讨论的 23 种[设计模式](https://howtodoinjava.com/gang-of-four-java-design-patterns/)之一。 **纪念图案**用于将对象的状态恢复到先前的状态。 也称为**快照模式**
备忘录就像对象生命周期中的还原点,客户端应用可使用该还原点将对象状态还原为其状态。 从概念上讲,这很像我们为操作系统创建还原点,并在发生故障或系统崩溃时用于还原系统。
......
......@@ -2,7 +2,7 @@
> 原文: [https://howtodoinjava.com/design-patterns/behavioral/strategy-design-pattern/](https://howtodoinjava.com/design-patterns/behavioral/strategy-design-pattern/)
**策略设计模式**是行为设计​​模式,在该行为设计模式中,我们选择[算法](//howtodoinjava.com/java-algorithms-implementations/)或任务在运行时的特定实现 - 从同一任务的多个其他实现中选择。
**策略设计模式**是行为设计​​模式,在该行为设计模式中,我们选择[算法](//howtodoinjava.com/java-algorithms-implementations/)或任务在运行时的特定实现 - 从同一任务的多个其他实现中选择。
重要的一点是,这些实现是可互换的 – 根据任务可以选择一种实现而不会干扰应用工作流程。
......@@ -245,7 +245,7 @@ Connecting with Lokesh through Orkut [not possible though :)]
* 此模式定义了一组相关算法,并将它们封装在单独的类中,并允许客户端在运行时选择任何算法。
* 它允许添加新算法而无需修改使用算法或策略的现有算法或上下文类
* 策略是“四个设计的帮派”列表中的一种行为模式。
* 策略是“四个设计的帮派”列表中的一种行为模式。
* 策略模式基于 SOLID 主体的开放式封闭设计原则。
* Collections.sort()和 Comparator 接口的组合是 Strategy 模式的可靠示例。
......
......@@ -2,7 +2,7 @@
> 原文: [https://howtodoinjava.com/design-patterns/behavioral/template-method-pattern/](https://howtodoinjava.com/design-patterns/behavioral/template-method-pattern/)
**模板方法设计模式**是广泛接受的行为设计模式,用于在编程的上下文中实现某种[算法](//howtodoinjava.com/java-algorithms-implementations/)(固定的步骤集)。
**模板方法设计模式**是广泛接受的行为设计模式,用于在编程的上下文中实现某种[算法](//howtodoinjava.com/java-algorithms-implementations/)(固定的步骤集)。
它定义了执行多步算法的顺序步骤,并且还可以选择提供默认实现(根据要求)。
......
......@@ -2,7 +2,7 @@
> 原文: [https://howtodoinjava.com/design-patterns/behavioral/visitor-design-pattern-example-tutorial/](https://howtodoinjava.com/design-patterns/behavioral/visitor-design-pattern-example-tutorial/)
[**设计模式**](//howtodoinjava.com/category/design-patterns/ "design patterns") 用于解决模式中出现的问题,我们都知道,对吧? 我们也知道 [**行为设计模式**](//howtodoinjava.com/category/design-patterns/behavioral/ "behavioral patterns") 是识别对象之间常见通信模式的设计模式。 这种行为模式之一是访客模式,我们将在本文中学习。
[**设计模式**](//howtodoinjava.com/category/design-patterns/ "design patterns") 用于解决模式中出现的问题,我们都知道,对吧? 我们也知道 [**行为型设计模式**](//howtodoinjava.com/category/design-patterns/behavioral/ "behavioral patterns") 是识别对象之间常见通信模式的设计模式。 这种行为型模式之一是访客模式,我们将在本文中学习。
如果您一直在处理管理大量产品的应用,那么您可以轻松地解决此问题:
......
> 原文: [https://howtodoinjava.com/design-patterns/structural/](https://howtodoinjava.com/design-patterns/structural/)
结构设计模式向您展示了如何以灵活和可扩展的方式将系统的不同部分粘合在一起。 它们可帮助您确保当其中一部分发生更改时,整个结构都不需要更改。
结构设计模式向您展示了如何以灵活和可扩展的方式将系统的不同部分粘合在一起。 它们可帮助您确保当其中一部分发生更改时,整个结构都不需要更改。
这些模式关注以下方面:类如何彼此继承以及如何从其他类组成。 结构模式使用继承来构成接口或实现。 结构对象模式描述了组成对象以实现新功能的方式
\ No newline at end of file
这些模式关注以下方面:类如何彼此继承以及如何从其他类组成。 结构型模式使用继承来构成接口或实现。 结构对象模式描述了组成对象以实现新功能的方式
\ No newline at end of file
......@@ -186,7 +186,7 @@ Support data - support link - - support popup -
要下载完整的源代码和 UML 图,请遵循文章结尾处的下载链接。
## 关于装饰图案的访谈问题
## 关于装饰图案的面试问题
**A)如何确定何时使用装饰器模式?**
......
......@@ -6,7 +6,7 @@
## 1.何时使用外墙图案
立面图案是**结构设计模式**中的一种,另外还有四个[设计模式](https://howtodoinjava.com/gang-of-four-java-design-patterns/)。 当我们有一个复杂的系统要以简化的方式向客户公开时,外观模式是合适的。 其目的是将内部复杂性隐藏在从外部看起来很简单的单个界面后面。
立面图案是**结构设计模式**中的一种,另外还有四个[设计模式](https://howtodoinjava.com/gang-of-four-java-design-patterns/)。 当我们有一个复杂的系统要以简化的方式向客户公开时,外观模式是合适的。 其目的是将内部复杂性隐藏在从外部看起来很简单的单个界面后面。
Facade 还可以将使用系统的代码与子系统的细节分离开来,从而使以后修改系统变得更加容易。
......
......@@ -223,7 +223,7 @@ Drawing THICK content in color : BLUE
类似于单例模式,如果我们在并发环境中创建 flyweight 对象,则最终可能会遇到同一个 flyweight 对象的多个实例,这是不希望的。
要解决此问题,我们需要在创建飞配重时使用[单例模式](https://howtodoinjava.com/design-patterns/creational/singleton-design-pattern-in-java/)中使用的**双重检查锁定**
要解决此问题,我们需要在创建飞配重时使用[单例模式](https://howtodoinjava.com/design-patterns/creational/singleton-design-pattern-in-java/)中使用的**双检锁**
#### 5.3 轻量化设计模式的好处
......
......@@ -6,7 +6,7 @@ Python 示例,用于解包元组或序列或可迭代,以便该元组可能
## 1.解开任意长度的元组
**Python“ `star expressions`”可用于解包任意长度的元组。**
**Python“`star expressions`”可用于解包任意长度的元组。**
```java
>>> employee = ('Lokesh', 'email@example.com', '111-222-333', '444-555-666')
......
......@@ -7,7 +7,7 @@
## Java 难题
* [Java 中的无效代码和无法访问的代码](//howtodoinjava.com/puzzles/dead-code-and-unreachable-code-in-java-puzzle/)
* [如何在不使用新关键字](//howtodoinjava.com/puzzles/how-to-create-an-instance-of-any-class-without-using-new-keyword/)的情况下创建任何类的实例
* [如何在不使用`new`新关键字](//howtodoinjava.com/puzzles/how-to-create-an-instance-of-any-class-without-using-new-keyword/)的情况下创建任何类的实例
* [检查回文编号](//howtodoinjava.com/puzzles/how-to-check-if-a-number-is-palindrome-in-java/)
* [如何检测 LinkedList](https://howtodoinjava.com/puzzles/how-to-detect-infinite-loop-in-linkedlist-in-java-with-example/) 中的无限循环
* [TreeMap 放置操作难题](//howtodoinjava.com/puzzles/java-puzzle-treemap-put-operation/)
......
......@@ -2,7 +2,7 @@
> 原文: [https://howtodoinjava.com/puzzles/dead-code-and-unreachable-code-in-java-puzzle/](https://howtodoinjava.com/puzzles/dead-code-and-unreachable-code-in-java-puzzle/)
学习识别 Java 中的无效代码和无法访问的代码。 在您的 [Java 访谈](https://howtodoinjava.com/java-interview-questions/)编码问题中可能会提出这样的谜题。
学习识别 Java 中的无效代码和无法访问的代码。 在您的 [Java 面试](https://howtodoinjava.com/java-interview-questions/)编码问题中可能会提出这样的谜题。
## 1.无效代码和无法访问的代码错误
......
......@@ -4,7 +4,7 @@
学习编写 **Java 程序以反转字符串**。 我们将首先看到**如何反转字符串**,我们还将看到**如何反转字符串**
[Java 访谈](https://howtodoinjava.com/java-interview-questions/)中,这是初学者常见的难题。 让我们记住这些解决方案以便快速调用。
[Java 面试](https://howtodoinjava.com/java-interview-questions/)中,这是初学者常见的难题。 让我们记住这些解决方案以便快速调用。
## 1\. Java 程序反转字符串
......
......@@ -2,7 +2,7 @@
> 原文: [https://howtodoinjava.com/puzzles/3-ways-to-calculate-factorial-in-java/](https://howtodoinjava.com/puzzles/3-ways-to-calculate-factorial-in-java/)
编写程序以用 Java 计算[阶乘](https://en.wikipedia.org/wiki/Factorial) – 可能是 [Java 访谈](//howtodoinjava.com/java-interview-questions/)期间的编码练习。 最好了解如何构建这样的析因程序。 让我们经历以下三种方式:
编写程序以用 Java 计算[阶乘](https://en.wikipedia.org/wiki/Factorial) – 可能是 [Java 面试](//howtodoinjava.com/java-interview-questions/)期间的编码练习。 最好了解如何构建这样的析因程序。 让我们经历以下三种方式:
## 1)使用迭代计算阶乘
......
......@@ -2,7 +2,7 @@
> 原文: [https://howtodoinjava.com/puzzles/find-missing-number-from-series/](https://howtodoinjava.com/puzzles/find-missing-number-from-series/)
[Java 访谈](https://howtodoinjava.com/java-interview-questions/)上,一个常见的难题是 – 从一系列数字或数组中找到缺失的数字。 这个难题已经在 Amazon.com 中问过。
[Java 面试](https://howtodoinjava.com/java-interview-questions/)上,一个常见的难题是 – 从一系列数字或数组中找到缺失的数字。 这个难题已经在 Amazon.com 中问过。
在这个 Java 难题中,您有一系列数字开头(例如 1….N),而该系列中恰好缺少一个数字。 您必须编写一个 **Java 程序来查找**系列中的缺失数字。
......
......@@ -2,7 +2,7 @@
> 原文: [https://howtodoinjava.com/puzzles/how-to-create-an-instance-of-any-class-without-using-new-keyword/](https://howtodoinjava.com/puzzles/how-to-create-an-instance-of-any-class-without-using-new-keyword/)
我们都知道如何创建任何类的对象。 在 Java 中创建对象的最简单方法是使用**新的**关键字。 让我们探讨一下 Java 中无需使用新关键字即可创建对象的其他方法。
我们都知道如何创建任何类的对象。 在 Java 中创建对象的最简单方法是使用**新的**关键字。 让我们探讨一下 Java 中无需使用`new`新关键字即可创建对象的其他方法。
```java
Table of contents
......
......@@ -4,7 +4,7 @@
未来几天有计划的面试吗? 本指南包含 100 多个 **Java 面试问题**,将帮助您针对经验丰富的开发人员以及从小型初创公司到大型公司的大多数 Java 核心面试问题进行修订。
从这些基本的核心 Java 问题开始。 我写这些教程是为了帮助您回答您可能会遇到的一些难题。 我试图在每个答案后面尽可能多地推理。 尽管如此,仍不可能在本指南中包含所有可能的问题,因此我在本访谈指南的末尾提供了一些很好的资源。
从这些基本的核心 Java 问题开始。 我写这些教程是为了帮助您回答您可能会遇到的一些难题。 我试图在每个答案后面尽可能多地推理。 尽管如此,仍不可能在本指南中包含所有可能的问题,因此我在本面试指南的末尾提供了一些很好的资源。
## 1.核心 Java 面试问题
......@@ -249,7 +249,7 @@ ThreadPoolExecutor 将任务创建和执行分开。 使用 ThreadPoolExecutor
* 什么是基于 Spring Java 的配置?
* 解释 Spring Bean 的生命周期?
* Spring Bean 范围有哪些不同?
* 在 Spring Framework 中,Singleton bean 线程安全吗?
* 在 Spring 框架中,单例 bean 线程安全吗?
* 解释 Bean 自动装配的不同模式?
* 用示例解释@Qualifier 注释?
* 构造函数注入和设置器注入之间的区别?
......@@ -303,7 +303,7 @@ Spring **AOP** (面向方面​​的编程)在某种意义上补充了 OOP
* 数据库连接泄漏?
* 编写程序以使用第三个变量交换两个数字?
* 编写程序对数组进行排序并删除重复项?
* Singleton 上编写程序?
*单例上编写程序?
* 写一个程序合并两个数组?
* final 和 final 关键字有什么用?
* 我可以将类声明为静态还是私有的吗?
......
......@@ -7,7 +7,7 @@
## Java 难题
* [Java 中的无效代码和无法访问的代码](//howtodoinjava.com/puzzles/dead-code-and-unreachable-code-in-java-puzzle/)
* [如何在不使用新关键字](//howtodoinjava.com/puzzles/how-to-create-an-instance-of-any-class-without-using-new-keyword/)的情况下创建任何类的实例
* [如何在不使用`new`新关键字](//howtodoinjava.com/puzzles/how-to-create-an-instance-of-any-class-without-using-new-keyword/)的情况下创建任何类的实例
* [检查回文编号](//howtodoinjava.com/puzzles/how-to-check-if-a-number-is-palindrome-in-java/)
* [如何检测 LinkedList](https://howtodoinjava.com/puzzles/how-to-detect-infinite-loop-in-linkedlist-in-java-with-example/) 中的无限循环
* [TreeMap 放置操作难题](//howtodoinjava.com/puzzles/java-puzzle-treemap-put-operation/)
......
......@@ -81,7 +81,7 @@ String str = "abc";
上面的代码使 JVM 验证是否已经有一个字符串“ abc”(相同的字符序列)。 如果存在这样的字符串,则 JVM 仅将现有对象的引用分配给变量`str`,否则,将创建一个新的对象“ abc”,并将其引用分配给变量`str`
#### 2)使用新关键字
#### 2)使用`new`新关键字
```java
......
......@@ -115,7 +115,7 @@ Java 中的`String`与其他任何编程语言一样,都是字符序列。 这
## 解释 HashMap 的工作。 如何解决重复冲突?
你们大多数人都会同意,HashMap 是当今访谈中最喜欢讨论的话题。 如果有人要我描述“ HashMap 如何工作?”,我只是回答:“ **关于哈希**的原理”。 就这么简单。
你们大多数人都会同意,HashMap 是当今面试中最喜欢讨论的话题。 如果有人要我描述“ HashMap 如何工作?”,我只是回答:“ **关于哈希**的原理”。 就这么简单。
现在,以最简单的形式进行哈希处理是一种在对属性应用任何公式/算法之后为任何变量/对象分配唯一代码的方法。
......
# Java 访谈的 40 个热门问答集
# Java 面试的 40 个热门问答集
> 原文: [https://howtodoinjava.com/interview-questions/useful-java-collection-interview-questions/](https://howtodoinjava.com/interview-questions/useful-java-collection-interview-questions/)
毫无疑问,java 集合是最重要的领域之一,无论您是初级还是高级,您都可以在任何位置对其进行测试。 范围如此之广,几乎不可能涵盖所有问题。 但是,根据我以前的访谈,我尝试提出您必须知道的尽可能多的 GOOD **java 集合访谈问题**
毫无疑问,java 集合是最重要的领域之一,无论您是初级还是高级,您都可以在任何位置对其进行测试。 范围如此之广,几乎不可能涵盖所有问题。 但是,根据我以前的面试,我尝试提出您必须知道的尽可能多的 GOOD **java 集合面试问题**
我的目标是初学者和高级问题,所以如果您发现一些基本问题,请多多包涵,因为它们对某些初级开发人员可能有用。
......@@ -130,7 +130,7 @@ Java 列表是元素的**“有序”集合。 该排序是基于**零的索引*
#### 6)如何将 String 数组转换为 arraylist?
这更多是一个程序性问题,在初学者水平上可以看到。 目的是检查收集工具类中申请人的知识。 现在,让我们了解 Collection 框架中有两个工具类,它们大多数在访谈中看到,即 **Collections 和 Arrays**
这更多是一个程序性问题,在初学者水平上可以看到。 目的是检查收集工具类中申请人的知识。 现在,让我们了解 Collection 框架中有两个工具类,它们大多数在面试中看到,即 **Collections 和 Arrays**
集合类提供了一些静态函数来对集合类型执行特定操作。 数组提供了要在数组类型上执行的工具功能。
......@@ -293,7 +293,7 @@ TreeMap 是 HashMap 的特殊形式。 **它维护 HashMap 类中缺少的键**
请注意,**所有插入映射的键都必须实现 Comparable 接口**(这是确定顺序的必要条件)。 此外,所有这些键必须相互可比较:k1.compareTo(k2)不得为映射中的任何键 k1 和 k2 抛出 ClassCastException。 如果用户尝试将键放入违反此约束的映射中(例如,用户尝试将字符串键放入其键为整数的映射中),则 put(Object key,Object value)调用将引发 ClassCastException 。
## Java 集合访谈 – 讲述差异问题
## Java 集合面试 – 讲述差异问题
#### 18)Set 和 List 之间的区别?
......@@ -355,7 +355,7 @@ SortedSet 是 TreeSet 实现的接口。 就是这样!
* LinkedList 允许进行固定时间的插入或删除,但只允许顺序访问元素。 换句话说,您可以向前或向后浏览列表,但是在中间抓取一个元素所花费的时间与列表的大小成正比。 另一方面,ArrayList 允许随机访问,因此您可以在固定时间内抓取任何元素。 但是,从末端开始的任何地方添加或删除,都需要将后面的所有元素移开,以形成开口或填补空白。
* LinkedList 比 ArrayList 具有更多的内存开销,因为在 ArrayList 中,每个索引仅保存实际的对象(数据),但是在 LinkedList 的情况下,每个节点都保存下一个和上一个节点的数据以及地址。
## 更多采访访谈问题
## 更多采访面试问题
#### 27)如何使收藏集只读?
......
......@@ -68,7 +68,7 @@ jaxbMarshaller.setProperty("jaxb.formatted.output", Boolean.TRUE);
所有 JAXB 供应器都必须支持以下属性集。 一些供应器可能支持其他属性。
* **`jaxb.encoding`** - 编组 XML 数据时使用的输出编码。 如果未指定此属性,则默认情况下`Marshaller`将使用“ `UTF-8`”。
* **`jaxb.encoding`** - 编组 XML 数据时使用的输出编码。 如果未指定此属性,则默认情况下`Marshaller`将使用“`UTF-8`”。
* **`jaxb.formatted.output`** - 值可以是`true``false``Marshaller`是否将使用换行符和缩进来格式化所得的 XML 数据。 默认值为`false`
* **`jaxb.schemaLocation`** – 允许客户端应用在生成的 XML 数据中指定`xsi:schemaLocation`属性。
* **`jaxb.noNamespaceSchemaLocation`** – 它允许客户端应用在生成的 XML 数据中指定`xsi:noNamespaceSchemaLocation`属性。
......
......@@ -8,7 +8,7 @@
就像 [SAX 解析器](https://howtodoinjava.com/xml/how-to-parse-an-xml-using-sax-parser-and-defaulthandler/)一样, [StAX API](https://docs.oracle.com/javase/tutorial/jaxp/stax/api.html) 设计用于解析 XML 流。 区别在于:
1. StAX 是“ `pull`” API。 SAX 是“ `push`” API。
1. StAX 是“`pull`” API。 SAX 是“`push`” API。
2. StAX 可以进行 XML 读取和写入。 SAX 只能读取 XML。
**StAX 是拉取样式 API** 。 这意味着您必须自己将 StAX 解析器从 XML 文件中的一个项目移动到另一个项目,就像使用标准[`Iterator`](https://howtodoinjava.com/java/collections/how-iterator-works-in-java/)或 JDBC [`ResultSet`](https://howtodoinjava.com/java/jdbc/jdbc-select-query-example/)一样。 然后,您可以通过 StAX 解析器访问 XML 文件中遇到的每个此类“项目”的 XML 信息。
......
......@@ -92,7 +92,7 @@ XPath 数据模型中有七种节点:
元素节点至少是 XML 源文档中每个属性的一个属性节点的父级。 **这些节点用于定义有关特定元素节点**的特征。
例如,在我们的 XML 片段“ `year`”中是一个属性节点。
例如,在我们的 XML 片段“`year`”中是一个属性节点。
#### 2.4 文字节点
......@@ -100,7 +100,7 @@ XPath 数据模型中有七种节点:
文本节点是纯净的文本。 文本节点需要包含尽可能多的文本。 *请记住,文本节点的下一个或上一个节点不能是另一个文本节点。*
例如,我们 XML 片段中的所有值都是文本节点,例如 “ `Snow Crash`”和“ `Neal Stephenson`”。
例如,我们 XML 片段中的所有值都是文本节点,例如 “`Snow Crash`”和“`Neal Stephenson`”。
#### 2.5 注释节点
......
......@@ -81,7 +81,7 @@ AJP 连接器使 Tomcat 只处理动态网页,而让纯 HTML 服务器(例
Tomcat 的默认配置包括名为 **localhost** 的主机。 可以通过在文件`C:\Windows\System32\drivers\etc\hosts`中写入一个条目来完成 **localhost** 与您的计算机之间的关联。
主机属性“`appBase`”定义了 Tomcat 安装文件夹中的应用目录。 然后,每个应用通过该目录中的路径进行标识。 唯一的例外是根路径,该路径已映射到空字符串。 本地主机的应用基本目录是`webapps`。 这意味着目录“ `C:\Program Files\Apache Software Foundation\Tomcat 6.0\webapps\ROOT\`”中的应用由空字符串标识。 因此,其 URL 为“`http://localhost:8080/`”。 对于驻留在根以外的目录中的其他应用,如“`C:\Program Files\Apache Software Foundation\Tomcat 6.0\webapps\myapp\`”,URL 类似于“ `http://localhost:8080/myapp/`”。
主机属性“`appBase`”定义了 Tomcat 安装文件夹中的应用目录。 然后,每个应用通过该目录中的路径进行标识。 唯一的例外是根路径,该路径已映射到空字符串。 本地主机的应用基本目录是`webapps`。 这意味着目录“`C:\Program Files\Apache Software Foundation\Tomcat 6.0\webapps\ROOT\`”中的应用由空字符串标识。 因此,其 URL 为“`http://localhost:8080/`”。 对于驻留在根以外的目录中的其他应用,如“`C:\Program Files\Apache Software Foundation\Tomcat 6.0\webapps\myapp\`”,URL 类似于“`http://localhost:8080/myapp/`”。
属性`unpackWARs="true"`表示,如果将 WAR 文件拖放到`appBase`目录中,Tomcat 将自动将其扩展到普通文件夹中。 如果将此属性设置为`false`,则应用将直接从 WAR 文件运行。 这显然意味着应用的执行速度较慢,因为 Tomcat 需要在执行时解压缩 WAR 文件。
......
......@@ -24,6 +24,6 @@
/>
```
您都可以使用根路径“ `http://localhost/`”访问您的应用。
您都可以使用根路径“`http://localhost/`”访问您的应用。
**祝您学习愉快!**
\ No newline at end of file
......@@ -13,7 +13,7 @@ Enabling Directory Listing for any particular Webapp
## 为所有 Webapp 启用目录列表
要为所有 Web 应用启用目录列表,您可以通过将“`default`” servlet 的“ `listings`”从“`false`”更改为“`true`”来修改`<CATALINA_HOME>\conf\web.xml`,如下所示:
要为所有 Web 应用启用目录列表,您可以通过将“`default`” servlet 的“`listings`”从“`false`”更改为“`true`”来修改`<CATALINA_HOME>\conf\web.xml`,如下所示:
```java
<!-- The default servlet for all web applications, that serves static -->
......
......@@ -51,7 +51,7 @@ Servlet 类由其类加载器通过**延迟加载或急切加载**动态地加
![Lazy Loaded Servlet1](img/294ebfd4eeedec550a38116f4ed20cc6.png) ![Lazy Loaded Servlet](img/b0891aedc26651fe3a65387f03d81a7f.png)
**渴望加载 **Servlet****
**立即加载 **Servlet****
![Eagerly Loaded Servlet1](img/e917129361e32f00d214586083a50705.png) ![Eagerly Loaded Servlet](img/e034256511cf921b395c7f9f60892c0a.png)
......
......@@ -6,9 +6,9 @@
非常重要,让我们更详细地学习这些设计模式(在 Java 上下文中)。
## 1.创设计模式
## 1.创建型设计模式
创建模式通常用于代替构造函数的直接实例化。 它们使创建过程更具适应性和动态性。 特别是,它们可以为创建哪些对象,如何创建这些对象以及如何对其进行初始化提供很大的灵活性。
创建模式通常用于代替构造函数的直接实例化。 它们使创建过程更具适应性和动态性。 特别是,它们可以为创建哪些对象,如何创建这些对象以及如何对其进行初始化提供很大的灵活性。
| 设计模式名称 | 目的 |
| --- | --- |
......@@ -18,9 +18,9 @@
| [抽象工厂](//howtodoinjava.com/design-patterns/creational/abstract-factory-pattern-in-java/) | 每当我们需要对使用工厂模式创建的一组工厂进行另一个抽象级别时,就会使用抽象工厂模式。 |
| [单例](//howtodoinjava.com/design-patterns/singleton-design-pattern-in-java/) | 单例使应用每个 JVM 具有一个类的一个实例。 |
## 2.结构设计模式
## 2.结构设计模式
结构设计模式向我们展示了如何以灵活和可扩展的方式将系统的不同部分粘合在一起。 这些模式帮助我们确保当其中一部分发生更改时,整个应用结构都不需要更改。
结构设计模式向我们展示了如何以灵活和可扩展的方式将系统的不同部分粘合在一起。 这些模式帮助我们确保当其中一部分发生更改时,整个应用结构都不需要更改。
| 设计模式名称 | 目的 |
| --- | --- |
......@@ -32,9 +32,9 @@
| [享元](https://howtodoinjava.com/design-patterns/structural/flyweight-design-pattern/) | 享元设计模式允许使用对象共享,以有效支持大量细粒度的对象。 享元是一个共享对象,可以同时在多个上下文中使用。 享元在每种情况下都充当独立对象。 |
| [代理](https://howtodoinjava.com/design-patterns/structural/proxy-design-pattern/) | 在代理设计模式中,代理对象为另一个对象提供代理或占位符,以控制对其的访问。 代理大量用于实现与延迟加载相关的用例,在这种情况下,我们直到真正需要时才创建完整的对象。 |
## 3.行为设计模式
## 3.行为设计模式
行为模式抽象了我们要对采取该操作的对象或类采取的操作。 通过更改对象或类,我们可以更改所使用的算法,受影响的对象或行为,同时仍为客户端类保留相同的基本接口。
行为模式抽象了我们要对采取该操作的对象或类采取的操作。 通过更改对象或类,我们可以更改所使用的算法,受影响的对象或行为,同时仍为客户端类保留相同的基本接口。
| 设计模式名称 | 目的 |
| --- | --- |
......
# 创建型设计模式
> 原文: [https://howtodoinjava.com/design-patterns/creational/](https://howtodoinjava.com/design-patterns/creational/)
在软件工程中,创建设计模式是处理对象创建机制的设计模式,试图以适合情况的方式创建对象。 创新设计模式由两个主要思想组成。 一种是封装有关系统使用哪些具体类的知识。 另一个是隐藏如何创建和组合这些具体类的实例。
在软件工程中,创建型设计模式是处理对象创建机制的设计模式,试图以适合情况的方式创建对象。 创造型设计模式由两个主要思想组成。 一种是封装有关系统使用哪些具体类的知识。 另一个是隐藏如何创建和组合这些具体类的实例。
创建模式旨在将系统与对象的创建,组成和表示方式分开。 它们在创建对象的内容,对象,方式和时间方面增加了系统的灵活性。
创建模式旨在将系统与对象的创建,组成和表示方式分开。 它们在创建对象的内容,对象,方式和时间方面增加了系统的灵活性。
在以下情况下,请考虑应用创建模式:
在以下情况下,请考虑应用创建模式:
系统应独立于其对象和产品的创建方式。
一组相关的对象设计为可以一起使用。
隐藏类库或产品的实现,仅显示其接口。
构造独立复杂对象的不同表示形式。
类希望其子类实现其创建的对象。
类实例是在运行时指定的。
必须有一个实例,客户端可以随时访问该实例。
实例应该是可扩展的,无需进行修改。
\ No newline at end of file
+ 系统应独立于其对象和产品的创建方式。
+ 一组相关的对象设计为可以一起使用。
+ 隐藏类库或产品的实现,仅显示其接口。
+ 构造独立复杂对象的不同表示形式。
+ 类希望其子类实现其创建的对象。
+ 类实例是在运行时指定的。
+ 必须有一个实例,客户端可以随时访问该实例。
+ 实例应该是可扩展的,无需进行修改。
\ No newline at end of file
# Java Singleton 模式介绍
# Java 单例模式介绍
> 原文: [https://howtodoinjava.com/design-patterns/creational/singleton-design-pattern-in-java/](https://howtodoinjava.com/design-patterns/creational/singleton-design-pattern-in-java/)
......@@ -18,11 +18,11 @@ Table of Contents:
```
> 单例项是从其[数学对应项](https://en.wikipedia.org/wiki/Singleton_%28mathematics%29 "Singleton in mathematics")中得出的。 如上所述,它希望我们每个上下文只有一个实例。 在 Java 中,每个 JVM 一个实例。
> 单例术语是从其[数学对应术语](https://en.wikipedia.org/wiki/Singleton_%28mathematics%29 "Singleton in mathematics")中得出的。 如上所述,它希望我们每个上下文只有一个实例。 在 Java 中,每个 JVM 一个实例。
让我们看一下在 Java 中创建单例对象的可能解决方案。
## 1.渴望初始化的单例
## 1.立即初始化的单例
这是一种设计模式,其中的类实例实际上是在实际需要之前创建的。 通常,它是在系统启动时完成的。 在热切的初始化单例模式中,无论是否有其他类实际请求其实例,都将创建该单例实例。
......@@ -45,7 +45,7 @@ public class EagerSingleton {
让我们用下一种方法解决上述问题。
## 2.具有延迟初始化的单例
## 2.延迟初始化的单例
在计算机编程中,[延迟初始化](https://en.wikipedia.org/wiki/Lazy_initialization "lazy initilization")是将对象的创建,值的计算或其他昂贵的过程推迟到第一次使用时的策略。 在单例模式中,它将限制实例的创建,直到首次请求该实例为止。 让我们在代码中看到这一点:
......@@ -69,11 +69,11 @@ public final class LazySingleton {
```
第一次调用时,上述方法将检查是否已使用 instance 变量创建了实例。 如果没有实例,即实例为 null,它将创建一个实例并返回其引用。 如果实例已经创建,它将仅返回实例的引用。
第一次调用时,上述方法将检查是否已使用`instance`变量创建了实例。 如果没有实例,即实例为`null`,它将创建一个实例并返回其引用。 如果实例已经创建,它将仅返回实例的引用。
但是,这种方法也有其自身的缺点。 让我们看看如何。 假设有两个线程 T1 和 T2。 两者都来创建实例并检查是否`“instance==null”`。 现在,两个线程都将实例变量标识为 null,因此它们都假定必须创建一个实例。 他们依次进入同步块并创建实例。 最后,我们的应用中有两个实例。
可以使用[重检查锁定](https://en.wikipedia.org/wiki/Double_checked_locking_pattern#Usage_in_Java "double check locking")解决此错误。 该原理告诉我们在同步块中再次重新检查实例变量,如下所示:
可以使用[检锁](https://en.wikipedia.org/wiki/Double_checked_locking_pattern#Usage_in_Java "double check locking")解决此错误。 该原理告诉我们在同步块中再次重新检查实例变量,如下所示:
```java
public class LazySingleton {
......@@ -100,9 +100,9 @@ public class LazySingleton {
上面的代码是单例模式的正确实现。
Please be sure to use “[**volatile**](https://en.wikipedia.org/wiki/Volatile_variable#In_Java "volatile in java")” keyword with instance variable otherwise you can run into an out of order write error scenario, where reference of an instance is returned before actually the object is constructed i.e. JVM has only allocated the memory and constructor code is still not executed. In this case, your other thread, which refers to the uninitialized object may throw null pointer exception and can even crash the whole application.
请确保对实例变量使用[**`volatile`**](https://en.wikipedia.org/wiki/Volatile_variable#In_Java)关键字,否则您可能会遇到乱码的错误情况,在实例实际构造对象之前返回实例的引用,即 JVM 仅分配了内存,而构造函数代码仍未执行。 在这种情况下,引用未初始化对象的其他线程可能会引发空指针异常,甚至可能使整个应用程序崩溃。
## 3.具有静态块初始化的单例
## 3.使用静态块初始化的单例
如果您对类的加载顺序有所了解,则可以使用以下事实:即使在调用构造函数之前,也要在类的加载期间执行静态块。 我们可以在单例模式中使用此功能,如下所示:
......@@ -133,9 +133,9 @@ public class StaticBlockSingleton {
下一节将克服此问题。
## 4\. Singleton 与比尔·普格解决方案
## 4\. 单例与 Bill Pugh 解决方案
Bill Pugh 是 [java 内存模型](https://en.wikipedia.org/wiki/Java_Memory_Model "java memory model")更改背后的主要力量。 他的原则“ [按需初始化持有人惯用语](https://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom "bill pugh principle")”也使用了静态块的想法,但方式有所不同。 建议使用静态内部类。
Bill Pugh 是 [java 内存模型](https://en.wikipedia.org/wiki/Java_Memory_Model "java memory model")更改背后的主要力量。 他的原则“[按需初始化持有人惯例](https://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom "bill pugh principle")”也使用了静态块的想法,但方式有所不同。 建议使用静态内部类。
```java
public class BillPughSingleton {
......@@ -153,11 +153,11 @@ public class BillPughSingleton {
```
As you can see, until we need an instance, the LazyHolder class will not be initialized until required and you can still use other static members of BillPughSingleton class. ***This is the solution, i will recommend to use. I have used it in my all projects.***
如您所见,在需要实例之前,`LazyHolder`类直到需要时才会初始化,您仍然可以使用`BillPughSingleton`类的其他静态成员。 ***这是解决方案,我建议使用。 我在所有项目中都使用了它。***
## 5.使用枚举的单例
这种类型的实现使用枚举。 [枚举](https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html "enum in java")(如 java docs 中所写)为线程安全提供了隐式支持,并且仅保证了一个实例。 **Java 枚举单例**也是使单例花费最少的好方法。
这种类型的实现使用枚举。 [枚举](https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html "enum in java")(如 java 文档中所写)为线程安全提供了隐式支持,并且仅保证了一个实例。 **Java 枚举单例**也是使单例花费最少的好方法。
```java
public enum EnumSingleton {
......@@ -169,7 +169,7 @@ public enum EnumSingleton {
```
## 6.将 readResolve()添加到 Singleton 对象
## 6.将 `readResolve()`添加到单例对象
到目前为止,您必须已经决定如何实现单例。 现在,让我们看看即使在面试中也可能出现的其他问题。
......@@ -240,7 +240,7 @@ Output:
```
不幸的是,两个变量的变量“ `i`”的值不同。 显然,该类有两个实例。 因此,我们再次遇到应用中多个实例的相同问题。
不幸的是,两个变量的变量“`i`”的值不同。 显然,该类有两个实例。 因此,我们再次遇到应用中多个实例的相同问题。
要解决此问题,我们需要在`DemoSingleton`类中包含`readResolve()`方法。 当您反序列化对象时,将调用此方法。 在此方法的内部,必须返回现有实例以确保整个实例应用范围。
......@@ -280,7 +280,7 @@ public class DemoSingleton implements Serializable {
```
## 7.将 serialVersionUId 添加到单例对象
## 7.将`serialVersionUId`添加到单例对象
到目前为止,一切都很好。 到目前为止,我们已经解决了同步和序列化这两个问题。 现在,我们距正确而完整的实现仅一步之遥。 唯一缺少的部分是序列号。
......@@ -331,7 +331,7 @@ public class DemoSingleton implements Serializable {
学习愉快!
**实时单例示例** – 我只是想添加一些示例,以供进一步研究和在访谈中提及:
**实时单例示例** – 我只是想添加一些示例,以供进一步研究和在面试中提及:
* [java.awt.Desktop#getDesktop()](https://docs.oracle.com/javase/6/docs/api/java/awt/Desktop.html#getDesktop%28%29 "Desktop singelton")
* [java.lang.Runtime#getRuntime()](https://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html#getRuntime%28%29 "runtime")
\ No newline at end of file
* [`java.awt.Desktop#getDesktop()`](https://docs.oracle.com/javase/6/docs/api/java/awt/Desktop.html#getDesktop%28%29 "Desktop singelton")
* [`java.lang.Runtime#getRuntime()`](https://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html#getRuntime%28%29 "runtime")
\ No newline at end of file
# Java 中的生成器设计模式
# Java 中的构建器设计模式
> 原文: [https://howtodoinjava.com/design-patterns/creational/builder-pattern-in-java/](https://howtodoinjava.com/design-patterns/creational/builder-pattern-in-java/)
顾名思义, [**构建器模式**](https://en.wikipedia.org/wiki/Builder_pattern "Builder Pattern") 是构建复杂对象的**替代方法。 仅当您要使用相同的对象构建过程构建不同的不可变对象时,才应使用此方法。**
顾名思义, [**构建器模式**](https://en.wikipedia.org/wiki/Builder_pattern "Builder Pattern")是构建复杂对象的**替代方法**。 仅当您要使用相同的对象构建过程构建不同的不可变对象时,才应使用此方法。
在开始讨论之前,我想弄清楚我将在本文中讨论的构建器模式**与 GangOfFour“设计模式”书中提到的**稍有不同。 这本书说:
The builder pattern is a design pattern that allows for the step-by-step creation of complex objects using the correct sequence of actions. The construction is controlled by a director object that only needs to know the type of object it is to create.
构建器模式是一种设计模式,它允许使用正确的操作顺序逐步创建复杂的对象。 构造由导向对象控制,该导向对象仅需要知道要创建的对象的类型。
本书给出如下示例:
![Builder Pattern](img/b2566f075ded1691adfca9b5b1d4ce6c.png)
我真的很难在现实生活中的编程和应用中利用以上示例。 上面的过程与 [**抽象工厂**](//howtodoinjava.com/design-patterns/creational/abstract-factory-pattern-in-java/ "Abstract factory pattern in java") 模式非常相似(并非完全相似),在该模式中,您找到了特定类型对象的工厂(或生成器),然后工厂为您提供了具体的 该对象的实例。 **这个构建器模式与抽象工厂模式之间唯一的不同之处在于,构建器为您提供了对对象创建过程的更多控制,仅此而已。 除此之外,没有重大差异。**
我真的很难在现实生活中的编程和应用中利用以上示例。 上面的过程与[**抽象工厂**](//howtodoinjava.com/design-patterns/creational/abstract-factory-pattern-in-java/ "Abstract factory pattern in java")模式非常相似(并非完全相似),在该模式中,您找到了特定类型对象的工厂(或构建器),然后工厂为您提供了具体的 该对象的实例。 **这个构建器模式与抽象工厂模式之间唯一的不同之处在于,构建器为您提供了对对象创建过程的更多控制,仅此而已。 除此之外,没有重大差异。**
In one sentence, abstract factory pattern is the answer to `"WHAT"` and the builder pattern to `"HOW"`.
一句话,抽象工厂模式是对“`WHAT`”的回答,而构建器模式是对“`HOW`”的回答。
对我来说,构建器模式更像 [**流利接口**](https://en.wikipedia.org/wiki/Fluent_interface "Fluent_interface") 。 通常使用**方法级联**(或方法链接)来实现流利的接口。
对我来说,构建器模式更像[**流利的接口**](https://en.wikipedia.org/wiki/Fluent_interface "Fluent_interface") 。 通常使用**方法级联**(或方法链接)来实现流利的接口。
现在,从这里开始,我将以我认为在实际情况下特别有用的方式来讨论构建器模式。 我也希望说服你们。
......@@ -33,17 +33,17 @@ Conclusion
```
## 建造者模式的定义
## 构建器模式的定义
首先,给构建器模式一个定义:
> 生成器模式的目标是“将复杂对象的构造与其表示分开,以便同一构造过程可以创建不同的表示。”
> 构建器模式的目标是“将复杂对象的构造与其表示分开,以便同一构造过程可以创建不同的表示。”
## 我们需要构建器模式的地方
我们已经知道 [**不可变**](//howtodoinjava.com/java/related-concepts/how-to-make-a-java-class-immutable/ "How to make a java class immutable") 和不可变实例在应用中的好处。 如果对此有任何疑问,请让我想起 Java 中的`String`类。 正如我已经说过的那样,构建器模式可以帮助我们创建具有大量状态属性的不可变类。
我们已经知道[**不可变**](//howtodoinjava.com/java/related-concepts/how-to-make-a-java-class-immutable/ "How to make a java class immutable")和不可变实例在应用中的好处。 如果对此有任何疑问,请让我想起 Java 中的`String`类。 正如我已经说过的那样,构建器模式可以帮助我们创建具有大量状态属性的不可变类。
让我们讨论一下我们应用中的一个常见问题。 假设在任何用户管理模块中,主要实体都是`User`。 理想情况下,实际上,一旦完全创建了用户对象,您就不想更改其状态。 根本没有道理,对吧? 现在,假设我们的 User 对象具有以下 5 个属性,即`firstName``lastName``age``phone``address`
让我们讨论一下我们应用中的一个常见问题。 假设在任何用户管理模块中,主要实体都是`User`。 理想情况下,实际上,一旦完全创建了用户对象,您就不想更改其状态。 根本没有道理,对吧? 现在,假设我们的`User`对象具有以下 5 个属性,即`firstName``lastName``age``phone``address`
在通常的实践中,如果要创建不可变的`User`类,则必须将所有五个信息作为参数传递给构造函数。 它看起来像这样:
......@@ -58,7 +58,7 @@ public User (String firstName, String lastName, int age, String phone, String ad
```
很好。 现在,如果只有`firstName``lastName`是必不可少的**,剩下的 3 个字段是可选的,该怎么办。 问题! 我们需要更多的构造函数。**
很好。 现在,如果只有`firstName``lastName`是必不可少的,剩下的 3 个字段是可选的,该怎么办。 问题! 我们需要更多的构造函数。
```java
public User (String firstName, String lastName, int age, String phone){ ... }
......@@ -76,7 +76,7 @@ public User (String firstName, String lastName){ ... }
## 使用构建器模式的示例实现
下面是我们上面讨论的问题的编码解决方案。 这使用附加的类`UserBuilder`,该类可帮助我们构建具有所有必需属性和可选属性组合的所需 User 对象,而不会失去不变性。
下面是我们上面讨论的问题的编码解决方案。 这使用附加的类`UserBuilder`,该类可帮助我们构建具有所有必需属性和可选属性组合的所需`User`对象,而不会失去不变性。
```java
public class User
......@@ -196,21 +196,21 @@ User: Super, Man, 0, null, null
请注意,上面创建的用户对象**没有任何设置方法**,因此一旦建立,便无法更改其状态。 这提供了所需的不变性。
有时,开发人员将属性添加到 User 类时,可能会忘记为构建器添加对新属性的支持。 为了最大程度地减少这种情况,我们应该将构建器封装在它们所构建的类中(如上例所示),以使开发人员更清楚地知道也需要更新一个相关的构建器。
有时,开发人员将属性添加到`User`类时,可能会忘记为构建器添加对新属性的支持。 为了最大程度地减少这种情况,我们应该将构建器封装在它们所构建的类中(如上例所示),以使开发人员更清楚地知道也需要更新一个相关的构建器。
> 有时,我认为应该有一个**驱逐舰模式**(与构建器相对),该模式应该以系统的方式从复杂对象中拆除某些属性。 你怎么看?
## JDK 中的现有实现
[java.lang.Appendable](https://docs.oracle.com/javase/7/docs/api/java/lang/Appendable.html "Appendable") 的所有实现实际上都是在 Java 中使用 Builder 模式的良好示例。 例如:
[`java.lang.Appendable`](https://docs.oracle.com/javase/7/docs/api/java/lang/Appendable.html "Appendable") 的所有实现实际上都是在 Java 中使用 Builder 模式的良好示例。 例如:
[java.lang.StringBuilder#append()](https://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html#append%28java.lang.CharSequence%29 "StringBuilder") [未同步的类]
[`java.lang.StringBuilder#append()`](https://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html#append%28java.lang.CharSequence%29 "StringBuilder") [未同步的类]
[java.lang.StringBuffer#append()](https://docs.oracle.com/javase/1.5.0/docs/api/java/lang/StringBuffer.html#append%28java.lang.CharSequence%29 "StringBuffer") [同步类]
[`java.lang.StringBuffer#append()`](https://docs.oracle.com/javase/1.5.0/docs/api/java/lang/StringBuffer.html#append%28java.lang.CharSequence%29 "StringBuffer") [同步类]
[java.nio.ByteBuffer#put()](https://docs.oracle.com/javase/6/docs/api/java/nio/ByteBuffer.html#put%28java.nio.ByteBuffer%29 "ByteBuffer")(也在 CharBuffer,ShortBuffer,IntBuffer,LongBuffer,FloatBuffer 和 DoubleBuffer 上)
[`java.nio.ByteBuffer#put()`](https://docs.oracle.com/javase/6/docs/api/java/nio/ByteBuffer.html#put%28java.nio.ByteBuffer%29 "ByteBuffer")(也在 CharBuffer,ShortBuffer,IntBuffer,LongBuffer,FloatBuffer 和 DoubleBuffer 上)
另一种用法可以在 [javax.swing.GroupLayout.Group#addComponent()](https://docs.oracle.com/javase/6/docs/api/javax/swing/GroupLayout.Group.html#addComponent%28java.awt.Component%29 "GroupLayout")中找到。
另一种用法可以在[`javax.swing.GroupLayout.Group#addComponent()`](https://docs.oracle.com/javase/6/docs/api/javax/swing/GroupLayout.Group.html#addComponent%28java.awt.Component%29 "GroupLayout")中找到。
看看这些实现与我们上面讨论的相似。
......@@ -230,15 +230,15 @@ Temp1truefriend
毫无疑问,在构建器模式中,**代码行数增加了**至少增加了一倍,但是在**设计灵活性**和更多**可读代码**方面,努力得到了回报 。 构造函数的**参数被简化**,并在**高可读性方法调用**中提供。
构建器模式还有助于最大程度地减少构造函数中的参数数量,因此**不需要将可选参数** null 传递给构造函数。 真的吸引了我
构建器模式还有助于最大程度地减少构造函数中的参数数量,因此**不需要将可选参数**`null`传递给构造函数。 真的吸引了我
另一个好处是,对象总是以`complete`状态实例化,而不是处于不完整的状态,直到开发人员调用(如果曾经调用)适当的设置器方法来设置其他字段。
最后,我可以在对象构建过程中构建**不可变对象**,而无需太多复杂的逻辑。
## 建造者模式的成本与劣势
## 构建器模式的成本与劣势
尽管 Builder 模式减少了一些代码行,从而消除了使用设置器方法的需要,但仍然**中通过引入 Builder 对象使总行数**翻了一番。 此外,尽管客户代码更具可读性,但客户代码也更为冗长。 虽然对我而言,可读性比代码行更重要。
尽管构建器模式减少了一些代码行,从而消除了使用设置器方法的需要,但仍然**通过引入构建器对象使总行数**翻了一番。 此外,尽管客户代码更具可读性,但客户代码也更为冗长。 虽然对我而言,可读性比代码行更重要。
我能想到的唯一缺点。
......@@ -249,6 +249,9 @@ Temp1truefriend
参考文献
[http://en.wikipedia.org/wiki/Builder_pattern](https://en.wikipedia.org/wiki/Builder_pattern)
[http://www.javaspecialists.eu/archive/Issue163.html](http://www.javaspecialists.eu/archive/Issue163.html)
[http ://en.wikipedia.org/wiki/Fluent_interface](https://en.wikipedia.org/wiki/Fluent_interface)
[http://en.wikipedia.org/wiki/Fluent_interface](https://en.wikipedia.org/wiki/Fluent_interface)
[http://martinfowler.com/bliki/FluentInterface.html](http://martinfowler.com/bliki/FluentInterface.html)
\ No newline at end of file
......@@ -2,13 +2,13 @@
> 原文: [https://howtodoinjava.com/design-patterns/creational/implementing-factory-design-pattern-in-java/](https://howtodoinjava.com/design-patterns/creational/implementing-factory-design-pattern-in-java/)
在 Java 中创建类实例的最常用方法是什么? 大多数人会回答这个问题:“ *使用新关键字*”。 好吧,它现在被认为是老式的。 让我们看看如何?
在 Java 中创建类实例的最常用方法是什么? 大多数人会回答这个问题:“*使用`new`新关键字*”。 好吧,它现在被认为是老式的。 让我们看看如何?
如果对象创建代码散布在整个应用中,并且如果您需要更改对象创建过程,则需要在每个地方进行必要的更改。 在完成本文之后,在编写应用时,请考虑使用 **Java 工厂模式**
在我以前的文章“ Java 中的 [**单例设计模式”中,我们讨论了创建类实例的各种方法,以使同一 JVM 中不存在同一类的另一个实例。 。**](//howtodoinjava.com/design-patterns/singleton-design-pattern-in-java/ "Singleton design pattern in java")
在我以前的文章“ Java 中的 [**单例设计模式**](//howtodoinjava.com/design-patterns/singleton-design-pattern-in-java/ "Singleton design pattern in java")”中,我们讨论了创建类实例的各种方法,以使同一 JVM 中不存在同一类的另一个实例。
在这篇文章中,我将演示另一个创建模式,即[工厂模式](https://en.wikipedia.org/wiki/Factory_method_pattern "Factory pattern"),用于为您的类创建实例。 顾名思义,工厂是一个创建一些不同产品的地方,这些产品在功能上有些相似,但又分为几类。
在这篇文章中,我将演示另一个创建模式,即[工厂模式](https://en.wikipedia.org/wiki/Factory_method_pattern "Factory pattern"),用于为您的类创建实例。 顾名思义,工厂是一个创建一些不同产品的地方,这些产品在功能上有些相似,但又分为几类。
在 Java 中,工厂模式用于创建相同类型的不同类的实例。
......@@ -35,7 +35,7 @@ Table of Contents
## 2\. Java 工厂模式示例
到目前为止,我们已经设计了用于制造 **CarFactory** 的类。 现在创建它们。
到目前为止,我们已经设计了用于制造`CarFactory`的类。 现在创建它们。
#### 2.1 对象类型
......@@ -223,10 +223,10 @@ designPatterns.creational.factory.LuxuryCar@e9bfee2
**工厂模式最适合涉及一些复杂的对象创建步骤的地方**。 为确保这些步骤集中进行,并且不暴露于编写类中,应使用工厂模式。 我们可以在 JDK 本身中看到许多实时的工厂模式示例,例如:
* [java.sql.DriverManager#getConnection()](https://docs.oracle.com/javase/10/docs/api/java/sql/DriverManager.html#getConnection%28java.lang.String%29 "driver manager get connection")
* [java.net.URL#openConnection()](https://docs.oracle.com/javase/10/docs/api/java/net/URL.html#openConnection%28%29 "url open connection")
* [java.lang.Class#newInstance()](https://docs.oracle.com/javase/10/docs/api/java/lang/Class.html#newInstance%28%29 "class new instance")
* [java.lang.Class#forName()](https://docs.oracle.com/javase/10/docs/api/java/lang/Class.html#forName%28java.lang.String%29 "class forname")
* [`java.sql.DriverManager#getConnection()`](https://docs.oracle.com/javase/10/docs/api/java/sql/DriverManager.html#getConnection%28java.lang.String%29 "driver manager get connection")
* [`java.net.URL#openConnection()`](https://docs.oracle.com/javase/10/docs/api/java/net/URL.html#openConnection%28%29 "url open connection")
* [`java.lang.Class#newInstance()`](https://docs.oracle.com/javase/10/docs/api/java/lang/Class.html#newInstance%28%29 "class new instance")
* [`java.lang.Class#forName()`](https://docs.oracle.com/javase/10/docs/api/java/lang/Class.html#forName%28java.lang.String%29 "class forname")
希望我在此 **Java 工厂模式示例**中包含了足够的信息,以使该帖子内容丰富。
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册