From c5a4068e84f2dfd4dd6cd76125fcc66fb87679d2 Mon Sep 17 00:00:00 2001 From: Mike Liu Date: Sun, 1 Aug 2021 22:55:54 +0800 Subject: [PATCH] docs: Translation for zh (#1805) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add state and callback pattern * add command and template-method pattern * add iterator pattern * add bridege and DI pattern * fix issue #1600 * add converter,proxy,visitor pattern * add caching,composite,delegation,dirty-flag,interpreter patterns * add dao and producer-consumer * add dto and provate class data pattern * fix #1646 png path problems * fix #1646 composite png path case problem * add abstract document pattern and version-number pattern * add ambassador pattern * add acyclic-visitor and api-gateway pattern * add abstract-factory pattern * add active-object pattern * add aggregator-microservices and arrange-act-assert pattern * update async-method-invocation pattern * add balking and business-delegate pattern * add bytecode and circuit-break pattern * update arrange/act/assert pattern problems * add csch pattern * add language code, correct pic path * #1805 update permalink Co-authored-by: Subhrodip Mohanta Co-authored-by: Mike Co-authored-by: Ilkka Seppälä --- localization/zh/abstract-document/README.md | 4 +- localization/zh/abstract-factory/README.md | 4 +- localization/zh/active-object/README.md | 4 +- localization/zh/acyclic-visitor/README.md | 4 +- localization/zh/adapter/README.md | 4 +- .../zh/aggregator-microservices/README.md | 4 +- localization/zh/ambassador/README.md | 4 +- localization/zh/api-gateway/README.md | 4 +- localization/zh/arrange-act-assert/README.md | 10 +- .../zh/async-method-invocation/README.md | 57 +++-- localization/zh/balking/README.md | 48 ++-- localization/zh/bridge/README.md | 4 +- localization/zh/builder/README.md | 4 +- localization/zh/business-delegate/README.md | 50 ++-- localization/zh/bytecode/README.md | 235 ++++++++++++++++++ localization/zh/caching/README.md | 4 +- localization/zh/callback/README.md | 4 +- localization/zh/chain/README.md | 4 +- localization/zh/circuit-breaker/README.md | 115 +++++---- .../zh/cloud-static-content-hosting/README.md | 134 ++++++++++ localization/zh/collection-pipeline/README.md | 3 +- localization/zh/command/README.md | 4 +- localization/zh/composite-entity/README.md | 3 +- localization/zh/composite/README.md | 4 +- localization/zh/converter/README.md | 4 +- localization/zh/dao/README.md | 4 +- localization/zh/data-bus/README.md | 4 +- localization/zh/data-mapper/README.md | 3 +- .../zh/data-transfer-object/README.md | 4 +- localization/zh/decorator/README.md | 4 +- localization/zh/delegation/README.md | 4 +- .../zh/dependency-injection/README.md | 4 +- localization/zh/dirty-flag/README.md | 4 +- .../zh/double-checked-locking/README.md | 3 +- localization/zh/facade/README.md | 4 +- localization/zh/factory-kit/README.md | 3 +- localization/zh/factory-method/README.md | 4 +- localization/zh/factory/README.md | 3 +- localization/zh/interpreter/README.md | 4 +- localization/zh/iterator/README.md | 4 +- localization/zh/observer/README.md | 4 +- localization/zh/private-class-data/README.md | 4 +- localization/zh/producer-consumer/README.md | 4 +- localization/zh/proxy/README.md | 4 +- localization/zh/sharding/README.md | 3 +- localization/zh/state/README.md | 4 +- localization/zh/strategy/README.md | 4 +- localization/zh/template-method/README.md | 4 +- localization/zh/version-number/README.md | 6 +- localization/zh/visitor/README.md | 4 +- 50 files changed, 595 insertions(+), 221 deletions(-) create mode 100644 localization/zh/bytecode/README.md create mode 100644 localization/zh/cloud-static-content-hosting/README.md diff --git a/localization/zh/abstract-document/README.md b/localization/zh/abstract-document/README.md index 4bcff1da7..5bcb5e1e2 100644 --- a/localization/zh/abstract-document/README.md +++ b/localization/zh/abstract-document/README.md @@ -2,7 +2,7 @@ layout: pattern title: Abstract Document folder: abstract-document -permalink: /patterns/abstract-document/zh +permalink: /patterns/abstract-document/ categories: Structural language: zh tags: @@ -166,7 +166,7 @@ public class Car extends AbstractDocument implements HasModel, HasPrice, HasPart ## 类图 -![alt text](../../abstract-document/etc/abstract-document.png "Abstract Document Traits and Domain") +![alt text](../../../abstract-document/etc/abstract-document.png "Abstract Document Traits and Domain") ## 适用性 diff --git a/localization/zh/abstract-factory/README.md b/localization/zh/abstract-factory/README.md index b16be817a..0b2b109e4 100644 --- a/localization/zh/abstract-factory/README.md +++ b/localization/zh/abstract-factory/README.md @@ -2,7 +2,7 @@ layout: pattern title: Abstract Factory folder: abstract-factory -permalink: /patterns/abstract-factory/zh +permalink: /patterns/abstract-factory/ categories: Creational language: zh tags: @@ -168,7 +168,7 @@ public static void main(String[] args) { ## 类图 -![alt text](../../abstract-factory/etc/abstract-factory.urm.png "Abstract Factory class diagram") +![alt text](../../../abstract-factory/etc/abstract-factory.urm.png "Abstract Factory class diagram") ## 适用性 diff --git a/localization/zh/active-object/README.md b/localization/zh/active-object/README.md index c8e23c9c1..ae1a1724f 100644 --- a/localization/zh/active-object/README.md +++ b/localization/zh/active-object/README.md @@ -2,7 +2,7 @@ layout: pattern title: Active Object folder: active-object -permalink: /patterns/active-object/zh +permalink: /patterns/active-object/ categories: Concurrency language: zh tags: @@ -122,4 +122,4 @@ public class Orc extends ActiveCreature { ## 类图 -![alt text](../../active-object/etc/active-object.urm.PNG "Active Object class diagram") +![alt text](../../../active-object/etc/active-object.urm.PNG "Active Object class diagram") diff --git a/localization/zh/acyclic-visitor/README.md b/localization/zh/acyclic-visitor/README.md index 31c062457..965dc7a67 100644 --- a/localization/zh/acyclic-visitor/README.md +++ b/localization/zh/acyclic-visitor/README.md @@ -2,7 +2,7 @@ layout: pattern title: Acyclic Visitor folder: acyclic-visitor -permalink: /patterns/acyclic-visitor/zh +permalink: /patterns/acyclic-visitor/ categories: Behavioral language: zh tags: @@ -123,7 +123,7 @@ public class ConfigureForUnixVisitor implements ZoomVisitor { ## 类图 -![alt text](../../acyclic-visitor/etc/acyclic-visitor.png "Acyclic Visitor") +![alt text](../../../acyclic-visitor/etc/acyclic-visitor.png "Acyclic Visitor") ## 适用性 diff --git a/localization/zh/adapter/README.md b/localization/zh/adapter/README.md index 2e440d7bf..6add248fe 100644 --- a/localization/zh/adapter/README.md +++ b/localization/zh/adapter/README.md @@ -2,7 +2,7 @@ layout: pattern title: Adapter folder: adapter -permalink: /patterns/adapter/zh +permalink: /patterns/adapter/ categories: Structural language: zh tags: @@ -94,7 +94,7 @@ captain.row(); ``` ## 类图 -![alt text](../../adapter/etc/adapter.urm.png "Adapter class diagram") +![alt text](../../../adapter/etc/adapter.urm.png "Adapter class diagram") ## 应用 diff --git a/localization/zh/aggregator-microservices/README.md b/localization/zh/aggregator-microservices/README.md index 10b5ffeaa..dbca273c1 100644 --- a/localization/zh/aggregator-microservices/README.md +++ b/localization/zh/aggregator-microservices/README.md @@ -2,7 +2,7 @@ layout: pattern title: Aggregator Microservices folder: aggregator-microservices -permalink: /patterns/aggregator-microservices/zh +permalink: /patterns/aggregator-microservices/ categories: Architectural language: zh tags: @@ -95,7 +95,7 @@ curl http://localhost:50004/product ## 类图 -![alt text](../../aggregator-microservices/aggregator-service/etc/aggregator-service.png "Aggregator Microservice") +![alt text](../../../aggregator-microservices/aggregator-service/etc/aggregator-service.png "Aggregator Microservice") ## 适用性 diff --git a/localization/zh/ambassador/README.md b/localization/zh/ambassador/README.md index f96d87371..7b07e7b05 100644 --- a/localization/zh/ambassador/README.md +++ b/localization/zh/ambassador/README.md @@ -2,7 +2,7 @@ layout: pattern title: Ambassador folder: ambassador -permalink: /patterns/ambassador/zh +permalink: /patterns/ambassador/ categories: Structural language: zh tags: @@ -167,7 +167,7 @@ Service result: -1 ## 类图 -![alt text](../../ambassador/etc/ambassador.urm.png "Ambassador class diagram") +![alt text](../../../ambassador/etc/ambassador.urm.png "Ambassador class diagram") ## 适用性 diff --git a/localization/zh/api-gateway/README.md b/localization/zh/api-gateway/README.md index a41f004ca..2ce28b0d2 100644 --- a/localization/zh/api-gateway/README.md +++ b/localization/zh/api-gateway/README.md @@ -2,7 +2,7 @@ layout: pattern title: API Gateway folder: api-gateway -permalink: /patterns/api-gateway/zh +permalink: /patterns/api-gateway/ categories: Architectural language: zh tags: @@ -123,7 +123,7 @@ public class ApiGateway { ``` ## 类图 -![alt text](../../api-gateway/etc/api-gateway.png "API Gateway") +![alt text](../../../api-gateway/etc/api-gateway.png "API Gateway") ## 适用性 diff --git a/localization/zh/arrange-act-assert/README.md b/localization/zh/arrange-act-assert/README.md index 67849b8ac..b4b411206 100644 --- a/localization/zh/arrange-act-assert/README.md +++ b/localization/zh/arrange-act-assert/README.md @@ -2,7 +2,7 @@ layout: pattern title: Arrange/Act/Assert folder: arrange-act-assert -permalink: /patterns/arrange-act-assert/zh +permalink: /patterns/arrange-act-assert/ categories: Idiom language: zh tags: @@ -73,10 +73,7 @@ public class Cash { } ``` -Then we write our unit tests according to Arrange/Act/Assert pattern. Notice the clearly -separated steps for each unit test. - -然后我们根据Arrange / Act / Assert模式编写单元测试。 注意每个单元测试的步骤是分开的清晰的。 +然后我们根据安排/ 执行 / 断言模式编写单元测试。 注意每个单元测试的步骤是分开的清晰的。 ```java class CashAAATest { @@ -129,9 +126,8 @@ class CashAAATest { ## 适用性 -使用 Arrange/Act/Assert 模式当 +使用 安排/执行/断言 模式当 -* You need to structure your unit tests so that they're easier to read, maintain, and enhance. * 你需要结构化你的单元测试代码这样它们可以更好的阅读,维护和增强。 ## 鸣谢 diff --git a/localization/zh/async-method-invocation/README.md b/localization/zh/async-method-invocation/README.md index b71cd18f3..f5739c1e9 100644 --- a/localization/zh/async-method-invocation/README.md +++ b/localization/zh/async-method-invocation/README.md @@ -4,33 +4,32 @@ title: Async Method Invocation folder: async-method-invocation permalink: /patterns/async-method-invocation/ categories: Concurrency +language: zh tags: - Reactive --- -## 含义 +## 意图 -异步方法是一种调用线程在等待任务结果时候不会被阻塞的模式。该模式提供了对多个任务的并行处理,并通过回调或等待,在所有任务完成后在提供结果读取。 +异步方法调用是一个调用线程在等待任务结果时不会阻塞的模式。模式为多个独立的任务提供并行的处理方式并且通过回调或等到它们全部完成来接收任务结果。 ## 解释 -真实世界案例 +真实世界例子 -> 发射太空火箭是一项令人兴奋的事业。在任务指挥部下达发射命令后, 经过一些未确定的时间,火箭要么成功发射,要么重演挑战者悲剧。 +> 发射火箭是一项令人激动的事务。任务指挥官发出了发射命令,经过一段不确定的时间后,火箭要么成功发射,要么惨遭失败。 -简而言之 +通俗地说 -> 异步方法调用开始任务处理并,在任务结果准备好之前立即返回。任务处理的结果会在稍后再返回给调用者。 +> 异步方法调用开始任务处理,并在任务完成之前立即返回。 任务处理的结果稍后返回给调用方。 -维基百科的解释 +维基百科说 -> 在多线程计算机编程中,异步方法调用(AMI),也被称为异步方法调用或异步模式。这是一种设计模式,在这种模式下,调用点在等待被调用代码完成时不会被阻塞。相反,当返回点到达时,调用线程会得到通知。轮询结果是一种不受欢迎的选择。 +> 在多线程计算机编程中,异步方法调用(AMI),也称为异步方法调用或异步模式,是一种设计模式,其中在等待被调用的代码完成时不会阻塞调用站点。 而是在执行结果到达时通知调用线程。轮询调用结果是不希望的选项。 -**编程示例** +**程序示例** -在这个例子中,我们正在发射太空火箭和部署月球车。 - -该应用演示了异步方法调用模式。该模式的关键部分是 `AsyncResult`,它是一个异步计算值的中间容器,`AsyncCallback` 可以在任务完成时提供执行行动作,`AsyncExecutor` 负责管理异步任务的执行。 +在此示例中,我们正在发射太空火箭并部署月球漫游车。该应用演示了异步方法调用模式。 模式的关键部分是`AsyncResult`(用于异步评估值的中间容器),`AsyncCallback`(可以在任务完成时被执行)和`AsyncExecutor`(用于管理异步任务的执行)。 ```java public interface AsyncResult { @@ -54,7 +53,7 @@ public interface AsyncExecutor { } ``` -`ThreadAsyncExecutor` 是 `AsyncExecutor` 的一个实现。接下来将着重说明它的一些关键部分。 +`ThreadAsyncExecutor`是`AsyncExecutor`的实现。 接下来将突出显示其一些关键部分。 ```java public class ThreadAsyncExecutor implements AsyncExecutor { @@ -91,14 +90,14 @@ public class ThreadAsyncExecutor implements AsyncExecutor { } ``` -然后我们准备发射一些火箭,看看所有东西是如何一起运作的。 +然后,我们准备发射一些火箭,看看一切是如何协同工作的。 ```java public static void main(String[] args) throws Exception { - // construct a new executor that will run async tasks + // 构造一个将执行异步任务的新执行程序 var executor = new ThreadAsyncExecutor(); - // start few async tasks with varying processing times, two last with callback handlers + // 以不同的处理时间开始一些异步任务,最后两个使用回调处理程序 final var asyncResult1 = executor.startProcess(lazyval(10, 500)); final var asyncResult2 = executor.startProcess(lazyval("test", 300)); final var asyncResult3 = executor.startProcess(lazyval(50L, 700)); @@ -106,11 +105,11 @@ public static void main(String[] args) throws Exception { final var asyncResult5 = executor.startProcess(lazyval("callback", 600), callback("Deploying lunar rover")); - // emulate processing in the current thread while async tasks are running in their own threads - Thread.sleep(350); // Oh boy, we are working hard here + // 在当前线程中模拟异步任务正在它们自己的线程中执行 + Thread.sleep(350); // 哦,兄弟,我们在这很辛苦 log("Mission command is sipping coffee"); - // wait for completion of the tasks + // 等待任务完成 final var result1 = executor.endProcess(asyncResult1); final var result2 = executor.endProcess(asyncResult2); final var result3 = executor.endProcess(asyncResult3); @@ -118,13 +117,14 @@ public static void main(String[] args) throws Exception { asyncResult5.await(); // log the results of the tasks, callbacks log immediately when complete + // 记录任务结果的日志, 回调的日志会在回调完成时立刻记录 log("Space rocket <" + result1 + "> launch complete"); log("Space rocket <" + result2 + "> launch complete"); log("Space rocket <" + result3 + "> launch complete"); } ``` -以下是控制台输出。 +这是程序控制台的输出。 ```java 21:47:08.227 [executor-2] INFO com.iluwatar.async.method.invocation.App - Space rocket launched successfully @@ -140,22 +140,21 @@ public static void main(String[] args) throws Exception { 21:47:08.618 [main] INFO com.iluwatar.async.method.invocation.App - Space rocket <50> launch complete ``` -## 类图 +# 类图 -![alt text](../../async-method-invocation/etc/async-method-invocation.png "Async Method Invocation") +![alt text](../../../async-method-invocation/etc/async-method-invocation.png "Async Method Invocation") -## 适用场景 +## 适用性 -在以下场景可以使用异步调用模式 +在以下情况下使用异步方法调用模式 -* 你有多有可以并行执行的独立任务 -* 你需要提高一组串行任务的性能 -* 你的处理能力有限、或者有长期运行的任务,调用者不应该等待任务所有任务运行结束 +* 您有多个可以并行运行的独立任务 +* 您需要提高一组顺序任务的性能 +* 您的处理能力或长时间运行的任务数量有限,并且调用方不应等待任务执行完毕 -## 现实示例 +## 真实世界例子 * [FutureTask](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/FutureTask.html) * [CompletableFuture](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html) * [ExecutorService](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html) * [Task-based Asynchronous Pattern](https://msdn.microsoft.com/en-us/library/hh873175.aspx) - diff --git a/localization/zh/balking/README.md b/localization/zh/balking/README.md index 9d8ac095d..ef1b12e3f 100644 --- a/localization/zh/balking/README.md +++ b/localization/zh/balking/README.md @@ -4,33 +4,34 @@ title: Balking folder: balking permalink: /patterns/balking/ categories: Concurrency +language: zh tags: - Decoupling --- -## 含义 +## 意图 -阻止模式用于防止一个对象在不完整或不适当的状态下执行某段代码。 +止步模式用于防止对象在不完整或不合适的状态下执行某些代码。 ## 解释 -真实世界的案例 +真实世界例子 -> 洗衣机里有一个用于启动衣物洗涤的启动按钮。当洗衣机没有启动时,该按钮可以正常按下生效,但如果洗衣机已经在洗衣服了,再按下按钮就不生效了。 +> 洗衣机中有一个开始按钮,用于启动衣物洗涤。当洗衣机处于非活动状态时,按钮将按预期工作,但是如果已经在洗涤,则按钮将不起任何作用。 -简而言之 +通俗地说 -> 使用阻止模式,只有当对象处于特定状态时,才会执行某段代码。 +> 使用止步模式,仅当对象处于特定状态时才执行特定代码。 -维基百科的解释 +维基百科说 -> 阻止模式是一种软件设计模式,它只在对象处于特定状态时对其执行动作。例如,如果一个对象读取 ZIP 文件,当 ZIP 文件没有打开时,如果一个方法在该对象上调用一个获取方法,该对象就会对阻止这个请求。 +> 禁止模式是一种软件设计模式,仅当对象处于特定状态时才对对象执行操作。例如,一个对象读取zip压缩文件并在压缩文件没打开的时候调用get方法,对象将在请求的时候”止步“。 -**编程示例** +**程序示例** -在这个例子的实现中,`WashingMachine` 对象存在 2 种状态: `ENABLED` 和 `WASHING`。如果该对象处于 `ENABLED` 状态,则使用一个线程安全的方法可以其状态改变为 `WASHING`。在另一方面,如果它已经处于 `WASHING` 状态,而任何其他线程执行了 `wash()`,它不会执行该指令,而是什么都不做就返回。 +在此示例中,` WashingMachine`是一个具有两个状态的对象,可以处于两种状态:ENABLED和WASHING。 如果机器已启用,则使用线程安全方法将状态更改为WASHING。 另一方面,如果已经进行了清洗并且任何其他线程执行`wash()`,则它将不执行该操作,而是不执行任何操作而返回。 -以下是 `WashingMachine` 类的相关代码。 +这里是`WashingMachine` 类相关的部分。 ```java @Slf4j @@ -69,7 +70,7 @@ public class WashingMachine { } ``` -以下是 `WashingMachine` 使用的简单 `DelayProvider` 接口。 +这里是一个`WashingMachine`所使用的`DelayProvider`简单接口。 ```java public interface DelayProvider { @@ -77,7 +78,7 @@ public interface DelayProvider { } ``` -现在我们介绍一下使用 `WashingMachine` 的应用。 +现在,我们使用`WashingMachine`介绍该应用程序。 ```java public static void main(String... args) { @@ -96,7 +97,7 @@ public interface DelayProvider { } ``` -以下是程序的控制台输出。 +下面是程序的输出。 ``` 14:02:52.268 [pool-1-thread-2] INFO com.iluwatar.balking.WashingMachine - pool-1-thread-2: Actual machine state: ENABLED @@ -110,20 +111,21 @@ public interface DelayProvider { ## 类图 -![alt text](../../balking/etc/balking.png "Balking") +![alt text](../../../balking/etc/balking.png "Balking") -## 适用场景 +## 适用性 -在以下情况下可以使用阻止模式: -* 你想要在某个对象上调用一个动作,只有当该对象处于特定状态时才允许该调用。 -* 对象一般只处于容易暂时阻止的状态,只不过该时间是未知的。 +使用止步模式当 -## 教学 +* 您只想在对象处于特定状态时才对其调用操作 +* 对象通常仅处于容易暂时停止但状态未知的状态 -* [Guarded Suspension Pattern](https://java-design-patterns.com/patterns/guarded-suspension/) -* [Double Checked Locking Pattern](https://java-design-patterns.com/patterns/double-checked-locking/) +## 相关模式 -## 引用 +* [保护性暂挂模式](https://java-design-patterns.com/patterns/guarded-suspension/) +* [双重检查锁模式](https://java-design-patterns.com/patterns/double-checked-locking/) + +## 鸣谢 * [Patterns in Java: A Catalog of Reusable Design Patterns Illustrated with UML, 2nd Edition, Volume 1](https://www.amazon.com/gp/product/0471227293/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=0471227293&linkId=0e39a59ffaab93fb476036fecb637b99) diff --git a/localization/zh/bridge/README.md b/localization/zh/bridge/README.md index d4773583f..b1b770781 100644 --- a/localization/zh/bridge/README.md +++ b/localization/zh/bridge/README.md @@ -2,7 +2,7 @@ layout: pattern title: Bridge folder: bridge -permalink: /patterns/bridge/zh +permalink: /patterns/bridge/ categories: Structural language: zh tags: @@ -184,7 +184,7 @@ hammer.unwield(); ## 类图 -![alt text](../../bridge/etc/bridge.urm.png "Bridge class diagram") +![alt text](../../../bridge/etc/bridge.urm.png "Bridge class diagram") ## 适用性 diff --git a/localization/zh/builder/README.md b/localization/zh/builder/README.md index 6987dc6a4..953a2a5ad 100644 --- a/localization/zh/builder/README.md +++ b/localization/zh/builder/README.md @@ -2,7 +2,7 @@ layout: pattern title: Builder folder: builder -permalink: /patterns/builder/zh +permalink: /patterns/builder/ categories: Creational language: zh tags: @@ -114,7 +114,7 @@ var mage = new Hero.Builder(Profession.MAGE, "Riobard").withHairColor(HairColor. ## 类图 -![alt text](../../builder/etc/builder.urm.png "Builder class diagram") +![alt text](../../../builder/etc/builder.urm.png "Builder class diagram") ## 适用性 diff --git a/localization/zh/business-delegate/README.md b/localization/zh/business-delegate/README.md index 225d81556..bef906987 100644 --- a/localization/zh/business-delegate/README.md +++ b/localization/zh/business-delegate/README.md @@ -4,36 +4,32 @@ title: Business Delegate folder: business-delegate permalink: /patterns/business-delegate/ categories: Structural +language: zh tags: - Decoupling --- -## 含义 +## 意图 -业务委托模式(译者:国内也有翻译成业务代表模式)在表现层和业务层之间增加了一个抽象层。通过使用该模式,我们获得了各层之间的松散耦合,并封装了关于如何定位、连接和与构成应用程序的业务对象进行交互的知识。 +业务委托模式在表示层和业务层之间添加了一个抽象层。 通过使用该模式,我们获得了各层之间的松散耦合,并封装了有关如何定位,连接到组成应用程序的业务对象以及与之交互的逻辑。 ## 解释 -真实世界的案例 +真实世界例子 -> 一个手机应用程序承诺将现有的任何电影传输到你的手机上。它捕获了用户的搜索关键字内容,并将其传递给业务委托层。业务委托层选择最合适的视频流服务,并从该服务进行视频播放。 +> 手机应用程序承诺将现有的任何电影流式传输到您的手机。它捕获用户的搜索字符串,并将其传递给业务委托层。业务委托层选择最合适的视频流服务,然后从那里播放视频。 -简而言之 +通俗的说 -> 业务委托模式在表现层和业务层之间增加了一个抽象层。 +> 业务委托模式在表示层和业务层之间添加了一个抽象层。 -维基百科的解释 +维基百科说 -> Business delegate is a Java EE design pattern. This pattern is directing to reduce the coupling -> in between business services and the connected presentation tier, and to hide the implementation -> details of services (including lookup and accessibility of EJB architecture). Business delegates -> acts as an adaptor to invoke business objects from the presentation tier. -> -> 业务委托模式是一种 Java EE 设计模式。这种模式旨在减少业务服务和所连接的表现层之间的耦合度,并隐藏服务的实现细节(包括 EJB 架构的查询和可访问性)。业务代表作为一个适配器,从表现层调用业务对象。 +> 业务委托是一种Java EE设计模式。 该模式旨在减少业务服务与连接的表示层之间的耦合,并隐藏服务的实现细节(包括EJB体系结构的查找和可访问性)。 业务代表充当适配器,以从表示层调用业务对象。 -**编程示例** +**程序示例** -首先,我们实现了一个视频流服务的抽象,和几个具体实现。 +首先,我们有视频流服务的抽象类和一些它的实现。 ```java public interface VideoStreamingService { @@ -57,7 +53,7 @@ public class YouTubeService implements VideoStreamingService { } ``` -接下来,我们实现一个查询服务,用于决定使用哪个视频流服务。 +然后我们有一个查找服务来决定我们使用哪个视频流服务。 ```java @Setter @@ -76,7 +72,7 @@ public class BusinessLookup { } ``` -业务委托层使用业务查询,将电影播放请求路由到合适的视频流服务。 +业务委托类使用业务查找服务将电影播放请求路由到合适的视频流服务。 ```java @Setter @@ -108,7 +104,7 @@ public class MobileClient { } ``` -最后,我们展示一下这个示例完整的操作。 +最后我们展示完整示例。 ```java public static void main(String[] args) { @@ -127,7 +123,7 @@ public class MobileClient { } ``` -以下是终端输出的内容。 +这是控制台的输出。 ``` 21:15:33.790 [main] INFO com.iluwatar.business.delegate.NetflixService - NetflixService is now processing @@ -136,25 +132,25 @@ public class MobileClient { ## 类图 -![alt text](../../business-delegate/etc/business-delegate.urm.png "Business Delegate") +![alt text](../../../business-delegate/etc/business-delegate.urm.png "Business Delegate") ## 相关模式 -* [Service locator pattern](https://java-design-patterns.com/patterns/service-locator/) +* [服务定位器模式](https://java-design-patterns.com/patterns/service-locator/) -## 适用场景 +## 适用性 -业务委托模式的适用场景: +使用业务委托模式当 -* 你希望表现层和业务层之间是松耦合的。 -* 你想要协调对多个业务服务的调用。 -* 你想要对服务查询、服务调用进行封装。 +* 你希望表示层和业务层之间的松散耦合 +* 你想编排对多个业务服务的调用 +* 你希望封装查找服务和服务调用 ## 教程 * [Business Delegate Pattern at TutorialsPoint](https://www.tutorialspoint.com/design_pattern/business_delegate_pattern.htm) -## 引用 +## 鸣谢 * [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31) * [Core J2EE Patterns: Best Practices and Design Strategies](https://www.amazon.com/gp/product/0130648841/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=0130648841&linkId=a0100de2b28c71ede8db1757fb2b5947) diff --git a/localization/zh/bytecode/README.md b/localization/zh/bytecode/README.md new file mode 100644 index 000000000..4a280deaa --- /dev/null +++ b/localization/zh/bytecode/README.md @@ -0,0 +1,235 @@ +--- +layout: pattern +title: Bytecode +folder: bytecode +permalink: /patterns/bytecode/ +categories: Behavioral +language: zh +tags: + - Game programming +--- + +## 意图 + +允许编码行为作为虚拟机的指令。 + +## 解释 + +真实世界例子 + +> 一个团队正在开发一款新的巫师对战游戏。巫师的行为需要经过精心的调整和上百次的游玩测试。每次当游戏设计师想改变巫师行为时都让程序员去修改代码这是不妥的,所以巫师行为以数据驱动的虚拟机方式实现。 + +通俗地说 + +> 字节码模式支持由数据而不是代码驱动的行为。 + +[Gameprogrammingpatterns.com](https://gameprogrammingpatterns.com/bytecode.html) 中做了如下阐述: + +> 指令集定义了可以执行的低级操作。一系列指令被编码为字节序列。虚拟机一次一条地执行这些指令,中间的值用栈处理。通过组合指令,可以定义复杂的高级行为。 + +**程序示例** + +其中最重要的游戏对象是`巫师`类。 + +```java +@AllArgsConstructor +@Setter +@Getter +@Slf4j +public class Wizard { + + private int health; + private int agility; + private int wisdom; + private int numberOfPlayedSounds; + private int numberOfSpawnedParticles; + + public void playSound() { + LOGGER.info("Playing sound"); + numberOfPlayedSounds++; + } + + public void spawnParticles() { + LOGGER.info("Spawning particles"); + numberOfSpawnedParticles++; + } +} +``` + +下面我们展示虚拟机可用的指令。每个指令对于如何操作栈中的数据都有自己的语义。例如,增加指令,其取得栈顶的两个元素并把结果压入栈中。 + +```java +@AllArgsConstructor +@Getter +public enum Instruction { + + LITERAL(1), // e.g. "LITERAL 0", push 0 to stack + SET_HEALTH(2), // e.g. "SET_HEALTH", pop health and wizard number, call set health + SET_WISDOM(3), // e.g. "SET_WISDOM", pop wisdom and wizard number, call set wisdom + SET_AGILITY(4), // e.g. "SET_AGILITY", pop agility and wizard number, call set agility + PLAY_SOUND(5), // e.g. "PLAY_SOUND", pop value as wizard number, call play sound + SPAWN_PARTICLES(6), // e.g. "SPAWN_PARTICLES", pop value as wizard number, call spawn particles + GET_HEALTH(7), // e.g. "GET_HEALTH", pop value as wizard number, push wizard's health + GET_AGILITY(8), // e.g. "GET_AGILITY", pop value as wizard number, push wizard's agility + GET_WISDOM(9), // e.g. "GET_WISDOM", pop value as wizard number, push wizard's wisdom + ADD(10), // e.g. "ADD", pop 2 values, push their sum + DIVIDE(11); // e.g. "DIVIDE", pop 2 values, push their division + // ... +} +``` + +我们示例的核心是`虚拟机`类。 它将指令作为输入并执行它们以提供游戏对象行为。 + +```java +@Getter +@Slf4j +public class VirtualMachine { + + private final Stack stack = new Stack<>(); + + private final Wizard[] wizards = new Wizard[2]; + + public VirtualMachine() { + wizards[0] = new Wizard(randomInt(3, 32), randomInt(3, 32), randomInt(3, 32), + 0, 0); + wizards[1] = new Wizard(randomInt(3, 32), randomInt(3, 32), randomInt(3, 32), + 0, 0); + } + + public VirtualMachine(Wizard wizard1, Wizard wizard2) { + wizards[0] = wizard1; + wizards[1] = wizard2; + } + + public void execute(int[] bytecode) { + for (var i = 0; i < bytecode.length; i++) { + Instruction instruction = Instruction.getInstruction(bytecode[i]); + switch (instruction) { + case LITERAL: + // Read the next byte from the bytecode. + int value = bytecode[++i]; + // Push the next value to stack + stack.push(value); + break; + case SET_AGILITY: + var amount = stack.pop(); + var wizard = stack.pop(); + setAgility(wizard, amount); + break; + case SET_WISDOM: + amount = stack.pop(); + wizard = stack.pop(); + setWisdom(wizard, amount); + break; + case SET_HEALTH: + amount = stack.pop(); + wizard = stack.pop(); + setHealth(wizard, amount); + break; + case GET_HEALTH: + wizard = stack.pop(); + stack.push(getHealth(wizard)); + break; + case GET_AGILITY: + wizard = stack.pop(); + stack.push(getAgility(wizard)); + break; + case GET_WISDOM: + wizard = stack.pop(); + stack.push(getWisdom(wizard)); + break; + case ADD: + var a = stack.pop(); + var b = stack.pop(); + stack.push(a + b); + break; + case DIVIDE: + a = stack.pop(); + b = stack.pop(); + stack.push(b / a); + break; + case PLAY_SOUND: + wizard = stack.pop(); + getWizards()[wizard].playSound(); + break; + case SPAWN_PARTICLES: + wizard = stack.pop(); + getWizards()[wizard].spawnParticles(); + break; + default: + throw new IllegalArgumentException("Invalid instruction value"); + } + LOGGER.info("Executed " + instruction.name() + ", Stack contains " + getStack()); + } + } + + public void setHealth(int wizard, int amount) { + wizards[wizard].setHealth(amount); + } + // other setters -> + // ... +} +``` + +现在我们可以展示使用虚拟机的完整示例。 + +```java + public static void main(String[] args) { + + var vm = new VirtualMachine( + new Wizard(45, 7, 11, 0, 0), + new Wizard(36, 18, 8, 0, 0)); + + vm.execute(InstructionConverterUtil.convertToByteCode("LITERAL 0")); + vm.execute(InstructionConverterUtil.convertToByteCode("LITERAL 0")); + vm.execute(InstructionConverterUtil.convertToByteCode("GET_HEALTH")); + vm.execute(InstructionConverterUtil.convertToByteCode("LITERAL 0")); + vm.execute(InstructionConverterUtil.convertToByteCode("GET_AGILITY")); + vm.execute(InstructionConverterUtil.convertToByteCode("LITERAL 0")); + vm.execute(InstructionConverterUtil.convertToByteCode("GET_WISDOM")); + vm.execute(InstructionConverterUtil.convertToByteCode("ADD")); + vm.execute(InstructionConverterUtil.convertToByteCode("LITERAL 2")); + vm.execute(InstructionConverterUtil.convertToByteCode("DIVIDE")); + vm.execute(InstructionConverterUtil.convertToByteCode("ADD")); + vm.execute(InstructionConverterUtil.convertToByteCode("SET_HEALTH")); + } +``` + +下面是控制台输出。 + +``` +16:20:10.193 [main] INFO com.iluwatar.bytecode.VirtualMachine - Executed LITERAL, Stack contains [0] +16:20:10.196 [main] INFO com.iluwatar.bytecode.VirtualMachine - Executed LITERAL, Stack contains [0, 0] +16:20:10.197 [main] INFO com.iluwatar.bytecode.VirtualMachine - Executed GET_HEALTH, Stack contains [0, 45] +16:20:10.197 [main] INFO com.iluwatar.bytecode.VirtualMachine - Executed LITERAL, Stack contains [0, 45, 0] +16:20:10.197 [main] INFO com.iluwatar.bytecode.VirtualMachine - Executed GET_AGILITY, Stack contains [0, 45, 7] +16:20:10.197 [main] INFO com.iluwatar.bytecode.VirtualMachine - Executed LITERAL, Stack contains [0, 45, 7, 0] +16:20:10.197 [main] INFO com.iluwatar.bytecode.VirtualMachine - Executed GET_WISDOM, Stack contains [0, 45, 7, 11] +16:20:10.197 [main] INFO com.iluwatar.bytecode.VirtualMachine - Executed ADD, Stack contains [0, 45, 18] +16:20:10.197 [main] INFO com.iluwatar.bytecode.VirtualMachine - Executed LITERAL, Stack contains [0, 45, 18, 2] +16:20:10.198 [main] INFO com.iluwatar.bytecode.VirtualMachine - Executed DIVIDE, Stack contains [0, 45, 9] +16:20:10.198 [main] INFO com.iluwatar.bytecode.VirtualMachine - Executed ADD, Stack contains [0, 54] +16:20:10.198 [main] INFO com.iluwatar.bytecode.VirtualMachine - Executed SET_HEALTH, Stack contains [] +``` + +## 类图 + +![alt text](../../../bytecode/etc/bytecode.urm.png "Bytecode class diagram") + +## 适用性 + + + +当您需要定义很多行为并且游戏的实现语言不合适时,请使用字节码模式,因为: + +* 它的等级太低,使得编程变得乏味或容易出错。 +* 由于编译时间慢或其他工具问题,迭代它需要很长时间。 +* 它有太多的信任。 如果您想确保定义的行为不会破坏游戏,您需要将其与代码库的其余部分进行沙箱化。 + +## 相关模式 + +* [Interpreter](https://java-design-patterns.com/patterns/interpreter/) + +## 鸣谢 + +* [Game programming patterns](http://gameprogrammingpatterns.com/bytecode.html) diff --git a/localization/zh/caching/README.md b/localization/zh/caching/README.md index 91b9a72bc..aa2c61941 100644 --- a/localization/zh/caching/README.md +++ b/localization/zh/caching/README.md @@ -2,7 +2,7 @@ layout: pattern title: Caching folder: caching -permalink: /patterns/caching/zh +permalink: /patterns/caching/ categories: Behavioral language: zh tags: @@ -14,7 +14,7 @@ tags: 为了避免昂贵的资源重新获取,方法是在资源使用后不立即释放资源。资源保留其身份,保留在某些快速访问的存储中,并被重新使用,以避免再次获取它们。 ## 类图 -![alt text](../../caching/etc/caching.png "Caching") +![alt text](../../../caching/etc/caching.png "Caching") ## 适用性 在以下情况下使用缓存模式 diff --git a/localization/zh/callback/README.md b/localization/zh/callback/README.md index d704a6f45..9665355fb 100644 --- a/localization/zh/callback/README.md +++ b/localization/zh/callback/README.md @@ -2,7 +2,7 @@ layout: pattern title: Callback folder: callback -permalink: /patterns/callback/zh +permalink: /patterns/callback/ categories: Idiom language: zh tags: @@ -69,7 +69,7 @@ public final class SimpleTask extends Task { task.executeWith(() -> LOGGER.info("I'm done now.")); ``` ## 类图 -![alt text](../../callback/etc/callback.png "Callback") +![alt text](../../../callback/etc/callback.png "Callback") ## 适用性 使用回调模式当 diff --git a/localization/zh/chain/README.md b/localization/zh/chain/README.md index b193b9cee..0262868a9 100644 --- a/localization/zh/chain/README.md +++ b/localization/zh/chain/README.md @@ -2,7 +2,7 @@ layout: pattern title: Chain of responsibility folder: chain -permalink: /patterns/chain/zh +permalink: /patterns/chain/ categories: Behavioral language: zh tags: @@ -139,7 +139,7 @@ king.makeRequest(new Request(RequestType.COLLECT_TAX, "collect tax")); // Orc so ``` ## 类图 -![alt text](../../chain/etc/chain.urm.png "Chain of Responsibility class diagram") +![alt text](../../../chain/etc/chain.urm.png "Chain of Responsibility class diagram") ## 适用性 使用责任链模式当 diff --git a/localization/zh/circuit-breaker/README.md b/localization/zh/circuit-breaker/README.md index 1f2eaea76..e42d3940c 100644 --- a/localization/zh/circuit-breaker/README.md +++ b/localization/zh/circuit-breaker/README.md @@ -4,39 +4,45 @@ title: Circuit Breaker folder: circuit-breaker permalink: /patterns/circuit-breaker/ categories: Behavioral +language: zh tags: - Performance - Decoupling - Cloud distributed --- -## 含义 +## 意图 -以这样的方式(译者:指断路器方式)处理昂贵的远程服务调用,可以防止单个服务/组件的故障导致整个应用程序崩溃,同时我们可以尽快地进行服务重连。 +以这样一种方式处理昂贵的远程服务调用,即单个服务/组件的故障不会导致整个应用程序宕机,我们可以尽快重新连接到服务。 ## 解释 -现实世界案例 +真实世界例子 -> 设想一下,一个网络应用程序既有本地文件/图像,又有用于获取数据的远程服务。这些远程服务可能在某些时候是健康的、有反应的,也可能在某些时候由于各种原因而变得缓慢和无反应。因此,如果其中一个远程服务速度慢或不能成功响应,我们的应用程序将尝试使用多个线程/进程从远程服务中获取响应,很快所有的线程/进程都会挂起(也称为线程饥饿 thread starvation),从而导致我们整个 Web 应用程序崩溃。我们应该能够检测到这种情况,并向用户显示一个适当的信息,以便用户可以探索应用程序的其他部分,而不受远程服务故障的影响。同时,其他正常工作的服务应该保持运作,不受这次故障的影响。 +> 想象一个 Web 应用程序,它同时具有用于获取数据的本地文件/图像和远程服务。 这些远程服务有时可能健康且响应迅速,或者由于各种原因可能在某 个时间点变得缓慢和无响应。因此,如果其中一个远程服务缓慢或未成功响应,我们的应用程序将尝试使用多个线程/进程从远程服务获取响应,很快它们都会挂起(也称为 [线程饥饿][thread starvation](https://en.wikipedia.org/wiki/Starvation_(computer_science)))导致我们的整个 Web 应用程序崩溃。我们应该能够检测到这种情况并向用户显示适当的消息,以便他/她可以探索不受远程服务故障影响的应用程序的其他部分。 同时,其他正常工作的服务应保持正常运行,不受此故障的影响。 +> -简而言之 +通俗地说 -> 断路器允许优雅地处理失败的远程服务。当我们的应用程序的所有部分都高度解耦时,这种方式的效果会很好,一个组件的失败并不会导致其他部分停止工作。 +> 断路器允许优雅地处理失败的远程服务。当我们应用程序的所有部分彼此高度解耦时,它特别有用,一个组件的故障并不意味着其他部分将停止工作。 -维基百科的解释 +维基百科说 -> 断路器是现代软件开发中使用的一种设计模式。它用于检测故障,并封装了防止故障不断复发的逻辑,在维护期间,临时地处理外部系统故障或意外的系统问题。 +> 断路器是现代软件开发中使用的一种设计模式。 它用于检测故障并封装防止故障不断重复发生、维护期间、临时外部系统故障或意外系统困难的逻辑。 -## Programmatic Example +## 程序示例 -那么,这一切是如何实现的呢?考虑到上面的例子,我们将在一个简单的例子中模拟这个功能。一个监控服务(译者:下图的 Monitoring Service)模拟了网络应用,进行本地和远程调用。 +So, how does this all come together? With the above example in mind we will imitate the +functionality in a simple example. A monitoring service mimics the web app and makes both local and +remote calls. -该服务架构如下: +那么,这一切是如何结合在一起的呢? 记住上面的例子,我们将在一个简单的例子中模仿这个功能。 监控服务模仿 Web 应用程序并进行本地和远程调用。 -![alt text](../../circuit-breaker/etc/ServiceDiagram.png "Service Diagram") +服务架构如下: -终端用户(译者:上图的 End User)应用的代码如下: +![alt text](../../../circuit-breaker/etc/ServiceDiagram.png "Service Diagram") + +在代码方面,最终用户应用程序是: ```java @Slf4j @@ -61,44 +67,44 @@ public class App { var quickServiceCircuitBreaker = new DefaultCircuitBreaker(quickService, 3000, 2, 2000 * 1000 * 1000); - //Create an object of monitoring service which makes both local and remote calls + // 创建一个可以进行本地和远程调用的监控服务对象 var monitoringService = new MonitoringService(delayedServiceCircuitBreaker, quickServiceCircuitBreaker); - //Fetch response from local resource + // 获取本地资源 LOGGER.info(monitoringService.localResourceResponse()); - //Fetch response from delayed service 2 times, to meet the failure threshold + // 从延迟服务中获取响应 2 次,以满足失败阈值 LOGGER.info(monitoringService.delayedServiceResponse()); LOGGER.info(monitoringService.delayedServiceResponse()); - //Fetch current state of delayed service circuit breaker after crossing failure threshold limit - //which is OPEN now + // 在超过故障阈值限制后获取延迟服务断路器的当前状态 + // 现在是打开状态 LOGGER.info(delayedServiceCircuitBreaker.getState()); - //Meanwhile, the delayed service is down, fetch response from the healthy quick service + // 同时,延迟服务宕机,从健康快速服务获取响应 LOGGER.info(monitoringService.quickServiceResponse()); LOGGER.info(quickServiceCircuitBreaker.getState()); - //Wait for the delayed service to become responsive + // 等待延迟的服务响应 try { LOGGER.info("Waiting for delayed service to become responsive"); Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } - //Check the state of delayed circuit breaker, should be HALF_OPEN + // 检查延时断路器的状态,应该是HALF_OPEN LOGGER.info(delayedServiceCircuitBreaker.getState()); - //Fetch response from delayed service, which should be healthy by now + // 从延迟服务中获取响应,现在应该是健康的 LOGGER.info(monitoringService.delayedServiceResponse()); - //As successful response is fetched, it should be CLOSED again. + // 获取成功响应后,它的状态应该是关闭。 LOGGER.info(delayedServiceCircuitBreaker.getState()); } } ``` -监控服务代码(译者:上图的 monitoring service): +监控服务类: ```java public class MonitoringService { @@ -112,7 +118,7 @@ public class MonitoringService { this.quickService = quickService; } - //Assumption: Local service won't fail, no need to wrap it in a circuit breaker logic + // 假设:本地服务不会失败,无需将其包装在断路器逻辑中 public String localResourceResponse() { return "Local Service is working"; } @@ -144,7 +150,7 @@ public class MonitoringService { } } ``` -可以看出,它直接进行了获取本地资源的调用,但它把对远程(昂贵的)服务的调用包装在一个断路器对象中,这样可以防止出现如下故障: +可以看出,它直接调用获取本地资源,但它将对远程(昂贵)服务的调用包装在断路器对象中,防止故障如下: ```java public class DefaultCircuitBreaker implements CircuitBreaker { @@ -171,11 +177,11 @@ public class DefaultCircuitBreaker implements CircuitBreaker { DefaultCircuitBreaker(RemoteService serviceToCall, long timeout, int failureThreshold, long retryTimePeriod) { this.service = serviceToCall; - // We start in a closed state hoping that everything is fine + // 我们从关闭状态开始希望一切都是正常的 this.state = State.CLOSED; this.failureThreshold = failureThreshold; - // Timeout for the API request. - // Used to break the calls made to remote resource if it exceeds the limit + // API的超时时间. + // 用于在超过限制时中断对远程资源的调用 this.timeout = timeout; this.retryTimePeriod = retryTimePeriod; //An absurd amount of time in future which basically indicates the last failure never happened @@ -183,7 +189,7 @@ public class DefaultCircuitBreaker implements CircuitBreaker { this.failureCount = 0; } - // Reset everything to defaults + // 重置所有 @Override public void recordSuccess() { this.failureCount = 0; @@ -199,18 +205,18 @@ public class DefaultCircuitBreaker implements CircuitBreaker { this.lastFailureResponse = response; } - // Evaluate the current state based on failureThreshold, failureCount and lastFailureTime. + // 根据 failureThreshold、failureCount 和 lastFailureTime 评估当前状态。 protected void evaluateState() { if (failureCount >= failureThreshold) { //Then something is wrong with remote service if ((System.nanoTime() - lastFailureTime) > retryTimePeriod) { - //We have waited long enough and should try checking if service is up + // 我们已经等得够久了,应该尝试检查服务是否已启动 state = State.HALF_OPEN; } else { - //Service would still probably be down + // 服务可能仍会出现故障 state = State.OPEN; } } else { - //Everything is working fine + // 一切正常 state = State.CLOSED; } } @@ -253,16 +259,15 @@ public class DefaultCircuitBreaker implements CircuitBreaker { public String attemptRequest() throws RemoteServiceException { evaluateState(); if (state == State.OPEN) { - // return cached response if the circuit is in OPEN state + // 如果电路处于打开状态,则返回缓存的响应 return this.lastFailureResponse; } else { - // Make the API request if the circuit is not OPEN + // 如果电路未打开,则发出 API 请求 try { - //In a real application, this would be run in a thread and the timeout - //parameter of the circuit breaker would be utilized to know if service - //is working. Here, we simulate that based on server response itself + //在实际应用程序中,这将在线程中运行,并且将利用断路器的超时参数来了解服务 + // 是否正在工作。 在这里,我们根据服务器响应本身模拟 var response = service.call(); - // Yay!! the API responded fine. Let's reset everything. + // api 响应正常,重置所有。 recordSuccess(); return response; } catch (RemoteServiceException ex) { @@ -274,39 +279,39 @@ public class DefaultCircuitBreaker implements CircuitBreaker { } ``` -上述模式是如何防止失败的呢?让我们通过它所实现的这个有限状态机来了解。 +上述模式如何防止失败? 让我们通过它实现的这个有限状态机来理解。 -![alt text](../../circuit-breaker/etc/StateDiagram.png "State Diagram") +![alt text](../../../circuit-breaker/etc/StateDiagram.png "State Diagram") -- 我们用 `timeout`(超时)、 `failureThreshold` (失败阈值)、`retryTimePeriod`(重试时间周期) 参数初始化断路器对象 ,用于确定 API 的适应性。 -- 最初,断路器处于 `closed` 关闭状态,没有发生对 API 的远程调用。 -- 每次调用成功,我们就把状态重置为开始时的样子。 -- 如果失败的次数超过了一定的阈值(`failureThreshold`),断路器就会进入 `open` 开启状态,它的作用就像一个开启的电路,阻止远程服务的调用,从而节省资源。 -- 一旦我们超过重试时间周期(`retryTimePeriod`),断路器就会转到 `half-open` 半启用状态,并再次调用远程服务,检查服务是否正常,以便我们可以提供最新的响应内容。如果远程服务调用失败会使断路器回到 `open` 状态,并在重试超时后进行另一次尝试;如果远程服务调用成功则使断路器进入 `closed` 状态,这样一切又开始正常工作。 +- 我们使用某些参数初始化断路器对象:`timeout`、`failureThreshold` 和 `retryTimePeriod`,这有助于确定 API 的弹性。 +- 最初,我们处于“关闭”状态,没有发生对 API 的远程调用。 +- 每次调用成功时,我们都会将状态重置为开始时的状态。 +- 如果失败次数超过某个阈值,我们将进入“open”状态,这就像开路一样,阻止远程服务调用,从而节省资源。 (这里,我们从 API 返回名为 ```stale response``` 的响应) +- 一旦超过重试超时时间,我们就会进入“半开”状态并再次调用远程服务以检查服务是否正常工作,以便我们可以提供新鲜内容。 失败将其设置回“打开”状态,并在重试超时时间后进行另一次尝试,而成功将其设置为“关闭”状态,以便一切重新开始正常工作。 ## 类图 -![alt text](../../circuit-breaker/etc/circuit-breaker.urm.png "Circuit Breaker class diagram") +![alt text](../../../circuit-breaker/etc/circuit-breaker.urm.png "Circuit Breaker class diagram") -## 适用场景 +## 适用性 -在以下场景下,可以使用断路器模式: +在以下情况下使用断路器模式 -- 构建一个高可用的应用程序,某些些服务的失败不会导致整个应用程序的崩溃。 -- 构建一个持续运行(长期在线)的应用程序,以便其组件可以在不完全关闭的情况下进行升级。 +- 构建一个容错应用程序,其中某些服务的故障不应导致整个应用程序宕机。 +- 构建一个持续运行(永远在线)的应用程序,这样它的组件就可以在不完全关闭的情况下升级。 ## 相关模式 - [Retry Pattern](https://github.com/iluwatar/java-design-patterns/tree/master/retry) -## 现实案例 +## 真实世界例子 * [Spring Circuit Breaker module](https://spring.io/guides/gs/circuit-breaker) * [Netflix Hystrix API](https://github.com/Netflix/Hystrix) -## 引用 +## 鸣谢 * [Understanding Circuit Breaker Pattern](https://itnext.io/understand-circuitbreaker-design-pattern-with-simple-practical-example-92a752615b42) * [Martin Fowler on Circuit Breaker](https://martinfowler.com/bliki/CircuitBreaker.html) * [Fault tolerance in a high volume, distributed system](https://medium.com/netflix-techblog/fault-tolerance-in-a-high-volume-distributed-system-91ab4faae74a) -* [Circuit Breaker pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/circuit-breaker) \ No newline at end of file +* [Circuit Breaker pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/circuit-breaker) diff --git a/localization/zh/cloud-static-content-hosting/README.md b/localization/zh/cloud-static-content-hosting/README.md new file mode 100644 index 000000000..74bd385e0 --- /dev/null +++ b/localization/zh/cloud-static-content-hosting/README.md @@ -0,0 +1,134 @@ +--- +layout: pattern +title: Static Content Hosting +folder: cloud-static-content-hosting +permalink: /patterns/cloud-static-content-hosting/ +categories: Cloud +language: zh +tags: +- Cloud distributed +--- + +## 意图 + +将静态内容部署到基于云的存储服务,该服务可以将它们直接交付给客户端。 这可以减少对昂贵计算实例的需求。 + +## 解释 + +真实世界例子 + +> 全球性的营销网站(静态内容)需要快速的部署以开始吸引潜在的客户。为了将托管费用和维护成本降至最低,使用云托管存储服务和内容交付网络。 + +通俗地说 + +> 静态内容托管模式利用云原生存储服务来存储内容和全球内容交付网络,将其缓存在世界各地的多个数据中心。 在静态网站上,单个网页包含静态内容。 它们还可能包含客户端脚本,例如 Javascript。相比之下,动态网站依赖于服务器端处理,包括服务器端脚本,如 PHP、JSP 或 ASP.NET。 + +维基百科说 + +> 与由 Web 应用程序生成的动态网页相反,静态网页(有时称为平面网页或固定网页)是完全按照存储的方式传送到用户的网页浏览器的网页。静态网页适用于从不或很少需要更新的内容,尽管现代 +> Web 模板系统正在改变这一点。可以将大量静态页面作为文件进行维护,没有自动化工具(例如静态站点生成器)是不切实际的。 + +**示例** + +![alt text](../../../cloud-static-content-hosting/etc/static-content-hosting.png "Static Content Hosting") + +在这个例子中我们使用AWS S3创建一个静态网站,并利用 AWS Cloudfront 在全球范围内分发内容。 + +1. 首先你需要一个AWS账户,你可以在这个创建一个免费的:[AWS Free Tier](https://aws.amazon.com/free/free-tier/) + +2. 登陆 [AWS控制台](https://console.aws.amazon.com/console/home?nc2=h_ct&src=header-signin) + +3. 进入身份和接入管理服务 (IAM) . + +4. 创建一个仅具有此应用程序必要权限的IAM用户。 + + * 点击 `用户` + * 点击 `添加用户`. 选择你想要的 `用户名`, `接入类型`应该是 `编程式接入`. 点击 `下一步: 权限`. + * 选择 `直接附加已存在的策略`. 选择 `AmazonS3FullAccess` 和 `CloudFrontFullAccess`. Click `下一步: 标签`. + * 没有需要的标签, 所以直接点击 `下一步: 回顾`. + * 检查呈现的信息,没问题的话点击`创建用户` + * 完成这个示例所需要的`访问秘钥Id`和`访问秘钥密码`将会呈现在你面前,请妥善保管。 + * 点击 `关闭`. + +5. [安装AWS 命令行工具 (AWS CLI)](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv1.html) 来获得编程式访问AWS云。 + +6. 使用`aws configure`命令来配置AWS CLI [说明书](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-config) + +7. 为web站点创建AWS S3 bucket。 注意S3 bucket名字必须要在全球范围内唯一。 + + + * 语法是 `aws s3 mb ` [说明书](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-buckets-creating) + * 比如 `aws s3 mb s3://my-static-website-jh34jsjmg` + * 使用列出现有存储桶的命令`aws s3 ls`验证存储桶是否已成功创建 + +8. 使用命令`aws s3 website`来配置bucket作为web站点。 [说明书](https://docs.aws.amazon.com/cli/latest/reference/s3/website.html). + + * 比如`aws s3 website s3://my-static-website-jh34jsjmg --index-document index.html --error-document error.html` + +9. 上传内容到bucket中。 + * 首先创建内容,至少包含`index.html`和`error.html`文档。 + * 上传内容到你的bucket中。 [说明书](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-copy) + * 比如`aws s3 cp index.html s3://my-static-website-jh34jsjmg` and `aws s3 cp error.html s3://my-static-website-jh34jsjmg` + +10. 然后我们需要设置bucket的策略以允许读取访问。 + + * 使用以下内容创建`policy.json`(注意需要将bucket名称替换为自己的)。 + + ```json + { + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "PublicReadGetObject", + "Effect": "Allow", + "Principal": "*", + "Action": "s3:GetObject", + "Resource": "arn:aws:s3:::my-static-website-jh34jsjmg/*" + } + ] + } + ``` + + * 根据这些设置桶策略[说明书](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-bucket-policy.html) + * 比如 `aws s3api put-bucket-policy --bucket my-static-website-jh34jsjmg --policy file://policy.json` + +11. 使用浏览器测试web站点。 + + * web站点的URL格式是 `http://.s3-website-.amazonaws.com` + * 比如 这个站点创建在 `eu-west-1` 区域 ,名字是 `my-static-website-jh34jsjmg` 所以它可以通过 `http://my-static-website-jh34jsjmg.s3-website-eu-west-1.amazonaws.com`来访问。 + +12. 为web站点创建CloudFormation 分发。 + + * 语法文档在这里 [this reference](https://docs.aws.amazon.com/cli/latest/reference/cloudfront/create-distribution.html) + * 比如,最简单的方式是使用命令l `aws cloudfront create-distribution --origin-domain-name my-static-website-jh34jsjmg.s3.amazonaws.com --default-root-object index.html` + * 也支持JSON格式的配置 比如使用 `--distribution-config file://dist-config.json` 来传递分发的配置文件参数 + * 命令的舒勇将显示准确的分配配置项,包括包括可用于测试的生成的 CloudFront 域名,例如 `d2k3xwnaqa8nqx.cloudfront.net` + * CloudFormation 分发部署需要一些时间,但一旦完成,您的网站就会从全球各地的数据中心提供服务! + +13. 就是这样! 您已经实现了一个静态网站,其内容分发网络以闪电般的速度在世界各地提供服务。 + + * 要更新网站,您需要更新 S3 存储桶中的对象并使 CloudFront 分配中的对象无效 + * 要从 AWS CLI 执行此操作,请参阅 [this reference](https://docs.aws.amazon.com/cli/latest/reference/cloudfront/create-invalidation.html) + * 您可能想要做的进一步开发是通过 https 提供内容并为您的站点添加域名 + +## 适用性 + +当您想要执行以下操作时,请使用静态内容托管模式: + +* 最小化包含一些静态资源的网站和应用程序的托管成本。 +* 使用静态内容构建全球可用的网站 +* 监控网站流量、带宽使用、成本等。 + +## 典型用例 + +* 具有全球影响力的网站 +* 静态网站生成器生成的内容 +* 没有动态内容要求的网站 + +## 真实世界例子 + +* [Java Design Patterns web site](https://java-design-patterns.com) + +## 鸣谢 + +* [Static Content Hosting pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/static-content-hosting) diff --git a/localization/zh/collection-pipeline/README.md b/localization/zh/collection-pipeline/README.md index 87613100c..9077deae6 100644 --- a/localization/zh/collection-pipeline/README.md +++ b/localization/zh/collection-pipeline/README.md @@ -4,6 +4,7 @@ title: Collection Pipeline folder: collection-pipeline permalink: /patterns/collection-pipeline/ categories: Functional +language: zh tags: - Reactive --- @@ -13,7 +14,7 @@ tags: 在函数式编程中,可以通过一系列较小的模块化函数或操作来编排复杂的操作。这一系列函数被称为函数组合。当一个数据集合流经一个函数组合时,它就成为一个集合管道。函数组合和集合管道是函数式编程中经常使用的两种设计模式。 ## 类图 -![alt text](../../collection-pipeline/etc/collection-pipeline.png "Collection Pipeline") +![alt text](../../../collection-pipeline/etc/collection-pipeline.png "Collection Pipeline") ## 适用场景 在以下场景适用集合管道模式: diff --git a/localization/zh/command/README.md b/localization/zh/command/README.md index 201cb042c..a26533931 100644 --- a/localization/zh/command/README.md +++ b/localization/zh/command/README.md @@ -2,7 +2,7 @@ layout: pattern title: Command folder: command -permalink: /patterns/command/zh +permalink: /patterns/command/ categories: Behavioral language: zh tags: @@ -222,7 +222,7 @@ goblin.printStatus(); ``` ## 类图 -![alt text](../../command/etc/command.png "Command") +![alt text](../../../command/etc/command.png "Command") ## 适用性 使用命令模式当你想 diff --git a/localization/zh/composite-entity/README.md b/localization/zh/composite-entity/README.md index f38f30903..d15b64e39 100644 --- a/localization/zh/composite-entity/README.md +++ b/localization/zh/composite-entity/README.md @@ -4,6 +4,7 @@ title: Composite Entity folder: composite-entity permalink: /patterns/composite-entity/ categories: Structural +language: zh tags: - Enterprise Integration Pattern --- @@ -109,7 +110,7 @@ Arrays.stream(console.getData()).forEach(LOGGER::info); ## 类图 -![alt text](../../composite-entity/etc/composite_entity.urm.png "Composite Entity Pattern") +![alt text](../../../composite-entity/etc/composite_entity.urm.png "Composite Entity Pattern") ## 适用场景 diff --git a/localization/zh/composite/README.md b/localization/zh/composite/README.md index 6920190e2..4cfd29cb0 100644 --- a/localization/zh/composite/README.md +++ b/localization/zh/composite/README.md @@ -2,7 +2,7 @@ layout: pattern title: Composite folder: composite -permalink: /patterns/composite/zh +permalink: /patterns/composite/ categories: Structural language: zh tags: @@ -154,7 +154,7 @@ elfMessage.print(); // Much wind pours from your mouth. ## 类图 -![alt text](../../composite/etc/composite.urm.png "Composite class diagram") +![alt text](../../../composite/etc/composite.urm.png "Composite class diagram") ## 适用性 diff --git a/localization/zh/converter/README.md b/localization/zh/converter/README.md index 951a5c06b..1b8af5912 100644 --- a/localization/zh/converter/README.md +++ b/localization/zh/converter/README.md @@ -2,7 +2,7 @@ layout: pattern title: Converter folder: converter -permalink: /patterns/converter/zh +permalink: /patterns/converter/ categories: Creational language: zh tags: @@ -86,7 +86,7 @@ var user = userConverter.convertFromDto(dtoUser); ## 类图 -![alt text](../../converter/etc/converter.png "Converter Pattern") +![alt text](../../../converter/etc/converter.png "Converter Pattern") ## 适用性 diff --git a/localization/zh/dao/README.md b/localization/zh/dao/README.md index 388099773..c7e4614b6 100644 --- a/localization/zh/dao/README.md +++ b/localization/zh/dao/README.md @@ -2,7 +2,7 @@ layout: pattern title: Data Access Object folder: dao -permalink: /patterns/dao/zh +permalink: /patterns/dao/ categories: Architectural language: zh tags: @@ -149,7 +149,7 @@ customerDao.getAllCustomers(): java.util.stream.ReferencePipeline$Head@6ec8211c ## 类图 -![alt text](../../dao/etc/dao.png "Data Access Object") +![alt text](../../../dao/etc/dao.png "Data Access Object") ## 适用性 diff --git a/localization/zh/data-bus/README.md b/localization/zh/data-bus/README.md index 4eaa98914..d2fa730e7 100644 --- a/localization/zh/data-bus/README.md +++ b/localization/zh/data-bus/README.md @@ -3,8 +3,8 @@ layout: pattern title: Data Bus folder: data-bus permalink: /patterns/data-bus/ - categories: Architectural +language: zh tags: - Decoupling --- @@ -14,7 +14,7 @@ tags: 数据总线模式(译者:实际上,就是 Event-Bus 消息总线模式)允许在一个应用程序的组件之间收发消息/事件,而不需要这些组件相互感知,它们只需要知道所发送/接收的消息/事件的类型即可。 ## 类图 -![data bus pattern uml diagram](../../data-bus/etc/data-bus.urm.png "Data Bus pattern") +![data bus pattern uml diagram](../../../data-bus/etc/data-bus.urm.png "Data Bus pattern") ## 适用场景 可以在以下场景使用数据总线模式: diff --git a/localization/zh/data-mapper/README.md b/localization/zh/data-mapper/README.md index 4dc268fdb..a2c9ef188 100644 --- a/localization/zh/data-mapper/README.md +++ b/localization/zh/data-mapper/README.md @@ -4,6 +4,7 @@ title: Data Mapper folder: data-mapper permalink: /patterns/data-mapper/ categories: Architectural +language: zh tags: - Decoupling --- @@ -12,7 +13,7 @@ tags: 一个用于在持久化对象和数据库之间传输数据的映射器,同时保持它们之间和映射器本身的独立性。 ## 类图 -![alt text](../../data-mapper/etc/data-mapper.png "Data Mapper") +![alt text](../../../data-mapper/etc/data-mapper.png "Data Mapper") ## 适用场景 数据映射器适用于以下场景: diff --git a/localization/zh/data-transfer-object/README.md b/localization/zh/data-transfer-object/README.md index 36ed5cc7b..c9e938fde 100644 --- a/localization/zh/data-transfer-object/README.md +++ b/localization/zh/data-transfer-object/README.md @@ -2,7 +2,7 @@ layout: pattern title: Data Transfer Object folder: data-transfer-object -permalink: /patterns/data-transfer-object/zh +permalink: /patterns/data-transfer-object/ categories: Architectural language: zh tags: @@ -94,7 +94,7 @@ public class CustomerResource { ## 类图 -![alt text](../../data-transfer-object/etc/data-transfer-object.urm.png "data-transfer-object") +![alt text](../../../data-transfer-object/etc/data-transfer-object.urm.png "data-transfer-object") ## 适用性 diff --git a/localization/zh/decorator/README.md b/localization/zh/decorator/README.md index b7280cce7..dcb1ca8fe 100644 --- a/localization/zh/decorator/README.md +++ b/localization/zh/decorator/README.md @@ -2,7 +2,7 @@ layout: pattern title: Decorator folder: decorator -permalink: /patterns/decorator/zh +permalink: /patterns/decorator/ categories: Structural language: zh tags: @@ -106,7 +106,7 @@ clubbedTroll.fleeBattle(); // The troll shrieks in horror and runs away! ``` ## 类图 -![alt text](../../decorator/etc/decorator.urm.png "Decorator pattern class diagram") +![alt text](../../../decorator/etc/decorator.urm.png "Decorator pattern class diagram") ## 适用性 使用装饰者 diff --git a/localization/zh/delegation/README.md b/localization/zh/delegation/README.md index 1a7f418a0..40fb62024 100644 --- a/localization/zh/delegation/README.md +++ b/localization/zh/delegation/README.md @@ -2,7 +2,7 @@ layout: pattern title: Delegation folder: delegation -permalink: /patterns/delegation/zh +permalink: /patterns/delegation/ categories: Structural language: zh tags: @@ -16,7 +16,7 @@ tags: 它是一种让对象将某种行为向外部表达,但实际上将实现该行为的责任委托给关联对象的技术。 ## 类图 -![alt text](../../delegation/etc/delegation.png "Delegate") +![alt text](../../../delegation/etc/delegation.png "Delegate") ## 适用性 使用委托模式以实现以下目的 diff --git a/localization/zh/dependency-injection/README.md b/localization/zh/dependency-injection/README.md index 2ce1ef6dd..16262fa86 100644 --- a/localization/zh/dependency-injection/README.md +++ b/localization/zh/dependency-injection/README.md @@ -2,7 +2,7 @@ layout: pattern title: Dependency Injection folder: dependency-injection -permalink: /patterns/dependency-injection/zh +permalink: /patterns/dependency-injection/ categories: Creational language: zh tags: @@ -84,7 +84,7 @@ public class AdvancedWizard implements Wizard { ## 类图 -![alt text](../../dependency-injection/etc/dependency-injection.png "Dependency Injection") +![alt text](../../../dependency-injection/etc/dependency-injection.png "Dependency Injection") ## 适用性 diff --git a/localization/zh/dirty-flag/README.md b/localization/zh/dirty-flag/README.md index 2ef9308eb..12bd1c067 100644 --- a/localization/zh/dirty-flag/README.md +++ b/localization/zh/dirty-flag/README.md @@ -2,7 +2,7 @@ layout: pattern title: Dirty Flag folder: dirty-flag -permalink: /patterns/dirty-flag/zh +permalink: /patterns/dirty-flag/ categories: Behavioral language: zh tags: @@ -17,7 +17,7 @@ tags: 避免昂贵资源的重新获取。资源保留其身份,保留在某些快速访问的存储中,并被重新使用以避免再次获取它们。 ## 类图 -![alt text](../../dirty-flag/etc/dirty-flag.png "Dirty Flag") +![alt text](../../../dirty-flag/etc/dirty-flag.png "Dirty Flag") ## 适用性 在以下情况下使用脏标志模式 diff --git a/localization/zh/double-checked-locking/README.md b/localization/zh/double-checked-locking/README.md index 5a8a6312d..8a989b9f5 100644 --- a/localization/zh/double-checked-locking/README.md +++ b/localization/zh/double-checked-locking/README.md @@ -4,6 +4,7 @@ title: Double Checked Locking folder: double-checked-locking permalink: /patterns/double-checked-locking/ categories: Idiom +language: zh tags: - Performance --- @@ -12,7 +13,7 @@ tags: 通过先测试锁定标准("锁提示")而不实际获取锁的方式来减少获取锁的开销。只有当锁定标准检查表明需要锁定时,才进行实际的锁定逻辑。 ## 类图 -![alt text](../../double-checked-locking/etc/double_checked_locking_1.png "Double Checked Locking") +![alt text](../../../double-checked-locking/etc/double_checked_locking_1.png "Double Checked Locking") ## 适用场景 在以下场景适合使用双重锁检查模式: diff --git a/localization/zh/facade/README.md b/localization/zh/facade/README.md index 9bd36c95a..b49a7abd9 100644 --- a/localization/zh/facade/README.md +++ b/localization/zh/facade/README.md @@ -2,7 +2,7 @@ layout: pattern title: Facade folder: facade -permalink: /patterns/facade/zh +permalink: /patterns/facade/ categories: Structural language: zh tags: @@ -189,7 +189,7 @@ facade.endDay(); ``` ## 类图 -![alt text](../../facade/etc/facade.urm.png "Facade pattern class diagram") +![alt text](../../../facade/etc/facade.urm.png "Facade pattern class diagram") ## 适用性 使用外观模式当 diff --git a/localization/zh/factory-kit/README.md b/localization/zh/factory-kit/README.md index 4f4b58b59..c5c7a9884 100644 --- a/localization/zh/factory-kit/README.md +++ b/localization/zh/factory-kit/README.md @@ -4,6 +4,7 @@ title: Factory Kit folder: factory-kit permalink: /patterns/factory-kit/ categories: Creational +language: zh tags: - Extensibility --- @@ -12,7 +13,7 @@ tags: 使用分离的构建器和工厂接口来定义一个不可变内容的工厂。 ## 类图 -![alt text](../../factory-kit/etc/factory-kit.png "Factory Kit") +![alt text](../../../factory-kit/etc/factory-kit.png "Factory Kit") ## 适用场景 工厂套件模式适用于与以下场景: diff --git a/localization/zh/factory-method/README.md b/localization/zh/factory-method/README.md index fcb0c2b01..123721ba1 100644 --- a/localization/zh/factory-method/README.md +++ b/localization/zh/factory-method/README.md @@ -2,7 +2,7 @@ layout: pattern title: Factory Method folder: factory-method -permalink: /patterns/factory-method/zh +permalink: /patterns/factory-method/ categories: Creational language: zh tags: @@ -63,7 +63,7 @@ blacksmith.manufactureWeapon(WeaponType.AXE); ``` ## 类图 -![alt text](../../factory-method/etc/factory-method.urm.png "Factory Method pattern class diagram") +![alt text](../../../factory-method/etc/factory-method.urm.png "Factory Method pattern class diagram") ## 适用性 使用工厂方法模式当 diff --git a/localization/zh/factory/README.md b/localization/zh/factory/README.md index 414f1e7a9..19985c6f7 100644 --- a/localization/zh/factory/README.md +++ b/localization/zh/factory/README.md @@ -4,6 +4,7 @@ title: Factory folder: factory permalink: /patterns/factory/ categories: Creational +language: zh tags: - Gang of Four --- @@ -108,7 +109,7 @@ This is Ferrari. ## 类图 -![alt text](../../factory/etc/factory.urm.png "Factory pattern class diagram") +![alt text](../../../factory/etc/factory.urm.png "Factory pattern class diagram") ## 适用场景 diff --git a/localization/zh/interpreter/README.md b/localization/zh/interpreter/README.md index feafff9bd..126a70b79 100644 --- a/localization/zh/interpreter/README.md +++ b/localization/zh/interpreter/README.md @@ -2,7 +2,7 @@ layout: pattern title: Interpreter folder: interpreter -permalink: /patterns/interpreter/zh +permalink: /patterns/interpreter/ categories: Behavioral language: zh tags: @@ -13,7 +13,7 @@ tags: 给定一种语言,请定义其语法的表示形式,以及使用该表示形式来解释该语言中的句子的解释器。 ## 类图 -![alt text](../../interpreter/etc/interpreter_1.png "Interpreter") +![alt text](../../../interpreter/etc/interpreter_1.png "Interpreter") ## 适用性 有一种要解释的语言时,请使用解释器模式,并且可以将语言中的语句表示为抽象语法树。解释器模式在以下情况下效果最佳 diff --git a/localization/zh/iterator/README.md b/localization/zh/iterator/README.md index 257693a32..c7b6f0fad 100644 --- a/localization/zh/iterator/README.md +++ b/localization/zh/iterator/README.md @@ -2,7 +2,7 @@ layout: pattern title: Iterator folder: iterator -permalink: /patterns/iterator/zh +permalink: /patterns/iterator/ categories: Behavioral language: zh tags: @@ -115,7 +115,7 @@ while (itemIterator.hasNext()) { ``` ## 类图 -![alt text](../../iterator/etc/iterator_1.png "Iterator") +![alt text](../../../iterator/etc/iterator_1.png "Iterator") ## 适用性 以下情况使用迭代器模式 diff --git a/localization/zh/observer/README.md b/localization/zh/observer/README.md index 976e2da2f..e2417d4ff 100644 --- a/localization/zh/observer/README.md +++ b/localization/zh/observer/README.md @@ -2,7 +2,7 @@ layout: pattern title: Observer folder: observer -permalink: /patterns/observer/zh +permalink: /patterns/observer/ categories: Behavioral language: zh tags: @@ -129,7 +129,7 @@ public class Weather { ``` ## Class diagram -![alt text](../../observer/etc/observer.png "Observer") +![alt text](../../../observer/etc/observer.png "Observer") ## 应用 在下面任何一种情况下都可以使用观察者模式 diff --git a/localization/zh/private-class-data/README.md b/localization/zh/private-class-data/README.md index 76accc16c..6eb32a70f 100644 --- a/localization/zh/private-class-data/README.md +++ b/localization/zh/private-class-data/README.md @@ -2,7 +2,7 @@ layout: pattern title: Private Class Data folder: private-class-data -permalink: /patterns/private-class-data/zh +permalink: /patterns/private-class-data/ categories: Idiom language: zh tags: @@ -120,7 +120,7 @@ immutableStew.mix(); // Mixing the immutable stew we find: 2 potatoes, 4 carrot ## 类图 -![alt text](../../private-class-data/etc/private-class-data.png "Private Class Data") +![alt text](../../../private-class-data/etc/private-class-data.png "Private Class Data") ## 适用性 diff --git a/localization/zh/producer-consumer/README.md b/localization/zh/producer-consumer/README.md index 4cced03ba..8cda270b1 100644 --- a/localization/zh/producer-consumer/README.md +++ b/localization/zh/producer-consumer/README.md @@ -2,7 +2,7 @@ layout: pattern title: Producer Consumer folder: producer-consumer -permalink: /patterns/producer-consumer/zh +permalink: /patterns/producer-consumer/ categories: Concurrency language: zh tags: @@ -13,7 +13,7 @@ tags: 生产者消费者设计模式是一种经典的并发模式,通过将工作与执行工作任务分开来减少生产者与消费者之间的耦合。 ## 类图 -![alt text](../../producer-consumer/etc/producer-consumer.png "Producer Consumer") +![alt text](../../../producer-consumer/etc/producer-consumer.png "Producer Consumer") ## 适用性 在以下情况下使用生产者消费者 diff --git a/localization/zh/proxy/README.md b/localization/zh/proxy/README.md index 2ba8afe73..808b16505 100644 --- a/localization/zh/proxy/README.md +++ b/localization/zh/proxy/README.md @@ -2,7 +2,7 @@ layout: pattern title: Proxy folder: proxy -permalink: /patterns/proxy/zh +permalink: /patterns/proxy/ categories: Structural language: zh tags: @@ -123,7 +123,7 @@ Brown wizard is not allowed to enter! ## 类图 -![alt text](../../proxy/etc/proxy.urm.png "Proxy pattern class diagram") +![alt text](../../../proxy/etc/proxy.urm.png "Proxy pattern class diagram") ## 适用性 diff --git a/localization/zh/sharding/README.md b/localization/zh/sharding/README.md index b4b6073e0..71552bc48 100644 --- a/localization/zh/sharding/README.md +++ b/localization/zh/sharding/README.md @@ -4,6 +4,7 @@ title: Sharding folder: sharding permalink: /patterns/sharding/ categories: Behavioral +language: zh tags: - Performance - Cloud distributed @@ -15,7 +16,7 @@ tags: 一个分片本身就是一个数据存储(它可以包含许多不同类型的实体的数据),运行在作为存储节点的服务器上。 ## 类图 -![alt text](../../sharding/etc/sharding.urm.png "Sharding pattern class diagram") +![alt text](../../../sharding/etc/sharding.urm.png "Sharding pattern class diagram") ## 适用场景 这种设计模式提供了一下的好处: diff --git a/localization/zh/state/README.md b/localization/zh/state/README.md index 2ed8773c6..ba2d555d2 100644 --- a/localization/zh/state/README.md +++ b/localization/zh/state/README.md @@ -2,7 +2,7 @@ layout: pattern title: State folder: state -permalink: /patterns/state/zh +permalink: /patterns/state/ categories: Behavioral language: zh tags: @@ -135,7 +135,7 @@ public class Mammoth { ``` ## 类图 -![alt text](../../state/etc/state_urm.png "State") +![alt text](../../../state/etc/state_urm.png "State") ## 适用性 diff --git a/localization/zh/strategy/README.md b/localization/zh/strategy/README.md index 1ff49ef46..aee867b0a 100644 --- a/localization/zh/strategy/README.md +++ b/localization/zh/strategy/README.md @@ -2,7 +2,7 @@ layout: pattern title: Strategy folder: strategy -permalink: /patterns/strategy/zh +permalink: /patterns/strategy/ categories: Behavioral language: zh tags: @@ -112,7 +112,7 @@ public class DragonSlayer { ``` ## 类图 -![alt text](../../strategy/etc/strategy_1.png "Strategy") +![alt text](../../../strategy/etc/strategy_urm.png "Strategy") ## 应用 使用策略模式当 diff --git a/localization/zh/template-method/README.md b/localization/zh/template-method/README.md index 9fa5fbbe3..6bd40f032 100644 --- a/localization/zh/template-method/README.md +++ b/localization/zh/template-method/README.md @@ -2,7 +2,7 @@ layout: pattern title: Template method folder: template-method -permalink: /patterns/template-method/zh +permalink: /patterns/template-method/ categories: Behavioral language: zh tags: @@ -119,7 +119,7 @@ public class HalflingThief { ``` ## 类图 -![alt text](../../template-method/etc/template_method_urm.png "Template Method") +![alt text](../../../template-method/etc/template_method_urm.png "Template Method") ## 适用性 diff --git a/localization/zh/version-number/README.md b/localization/zh/version-number/README.md index ef447a123..f5985ab66 100644 --- a/localization/zh/version-number/README.md +++ b/localization/zh/version-number/README.md @@ -2,13 +2,13 @@ layout: pattern title: Version Number folder: versionnumber -permalink: /patterns/versionnumber/zh +permalink: /patterns/versionnumber/ description: Entity versioning with version number -language: zh categories: - Concurrency +language: zh tags: - Data access - Microservices @@ -135,7 +135,7 @@ Exception: Tried to update stale version 0 while actual version is 1 ## 类图 -![alt text](../../version-number/etc/version-number.urm.png "Version Number pattern class diagram") +![alt text](../../../version-number/etc/version-number.urm.png "Version Number pattern class diagram") ## 适用性 diff --git a/localization/zh/visitor/README.md b/localization/zh/visitor/README.md index b12a6f19a..2454032f0 100644 --- a/localization/zh/visitor/README.md +++ b/localization/zh/visitor/README.md @@ -2,7 +2,7 @@ layout: pattern title: Visitor folder: visitor -permalink: /patterns/visitor/zh +permalink: /patterns/visitor/ categories: Behavioral language: zh tags: @@ -201,7 +201,7 @@ Good to see you commander ## Class diagram -![alt text](../../visitor/etc/visitor_1.png "Visitor") +![alt text](../../../visitor/etc/visitor_1.png "Visitor") ## 适用性