From 0f966a2e88d81c6ea3ea3973ed23ef89fd9cdb74 Mon Sep 17 00:00:00 2001 From: jnniu-n <141746282+jnniu-n@users.noreply.github.com> Date: Thu, 26 Oct 2023 04:51:16 +1100 Subject: [PATCH] translation: Added Chinese Translation for Combinator and Monitor patterns (#2703) * Create combinator * translation for combinator and monitor to Chinese --- localization/zh/combinator/README.md | 207 ++++++++++++++++++ .../zh/combinator/etc/combinator.urm.png | Bin 0 -> 22657 bytes localization/zh/monitor/README.md | 95 ++++++++ localization/zh/monitor/etc/monitor.urm.png | Bin 0 -> 10483 bytes 4 files changed, 302 insertions(+) create mode 100644 localization/zh/combinator/README.md create mode 100644 localization/zh/combinator/etc/combinator.urm.png create mode 100644 localization/zh/monitor/README.md create mode 100644 localization/zh/monitor/etc/monitor.urm.png diff --git a/localization/zh/combinator/README.md b/localization/zh/combinator/README.md new file mode 100644 index 000000000..2e92be4ea --- /dev/null +++ b/localization/zh/combinator/README.md @@ -0,0 +1,207 @@ +--- +title: Combinator +category: Idiom +language: zh +tag: + - Reactive +--- + +## 或称 + +构图模式 + +## 目的 + +功能模式代表了一种以组合功能为中心的图书馆组织风格。 +简单地说,有一些类型 T,一些用于构造类型 T 的“原始”值的函数,以及一些可以以各种方式组合类型 T 的值以构建更复杂的类型 T 值的“组合器”。 + +## 解释 + +真实世界例子 + +> 在计算机科学中,组合逻辑被用作计算的简化模型,用于可计算性理论和证明理论。 尽管组合逻辑很简单,但它捕获了计算的许多基本特征。 +> + +通俗的说 +> 组合器允许从先前定义的“事物”创建新的“事物”。 +> + +维基百科说 + +> 组合器是一个高阶函数,仅使用函数应用程序和之前定义的组合器来定义其参数的结果。 +> + +**程序示例** + +翻译上面的组合器示例。 首先,我们有一个由几个方法`contains`, `not`, `or`, `and`组成的接口。 + +```java +// 用于查找文本中的行的功能界面。 +public interface Finder { + + // 在文本中查找行的函数。 + List find(String text); + + // 函数{@link #find(String)}的简单实现。 + static Finder contains(String word) { + return txt -> Stream.of(txt.split("\n")) + .filter(line -> line.toLowerCase().contains(word.toLowerCase())) + .collect(Collectors.toList()); + } + + // 组合器:not。 + default Finder not(Finder notFinder) { + return txt -> { + List res = this.find(txt); + res.removeAll(notFinder.find(txt)); + return res; + }; + } + + // 组合器:or。 + default Finder or(Finder orFinder) { + return txt -> { + List res = this.find(txt); + res.addAll(orFinder.find(txt)); + return res; + }; + } + + // 组合器:and。 + default Finder and(Finder andFinder) { + return + txt -> this + .find(txt) + .stream() + .flatMap(line -> andFinder.find(line).stream()) + .collect(Collectors.toList()); + } + ... +} +``` + +然后我们还有另一个组合器用于一些复杂的查找器`advancedFinder`, `filteredFinder`, `specializedFinder`和`expandedFinder`。 + +```java +// 由简单取景器组成的复杂取景器。 +public class Finders { + + private Finders() { + } + + // Finder 用于查找复杂的查询。 + public static Finder advancedFinder(String query, String orQuery, String notQuery) { + return + Finder.contains(query) + .or(Finder.contains(orQuery)) + .not(Finder.contains(notQuery)); + } + + // 过滤查找器也会查找包含排除查询的查询。 + public static Finder filteredFinder(String query, String... excludeQueries) { + var finder = Finder.contains(query); + + for (String q : excludeQueries) { + finder = finder.not(Finder.contains(q)); + } + return finder; + } + + // 专门查询。 每个下一个查询都会在上一个结果中查找。 + public static Finder specializedFinder(String... queries) { + var finder = identMult(); + + for (String query : queries) { + finder = finder.and(Finder.contains(query)); + } + return finder; + } + + // 扩展查询。 寻找替代品。 + public static Finder expandedFinder(String... queries) { + var finder = identSum(); + + for (String query : queries) { + finder = finder.or(Finder.contains(query)); + } + return finder; + } + ... +} +``` + +现在我们已经创建了组合器的接口和方法。 现在我们有一个处理这些组合器的应用程序。 + +```java +var queriesOr = new String[]{"many", "Annabel"}; +var finder = Finders.expandedFinder(queriesOr); +var res = finder.find(text()); +LOGGER.info("the result of expanded(or) query[{}] is {}", queriesOr, res); + +var queriesAnd = new String[]{"Annabel", "my"}; +finder = Finders.specializedFinder(queriesAnd); +res = finder.find(text()); +LOGGER.info("the result of specialized(and) query[{}] is {}", queriesAnd, res); + +finder = Finders.advancedFinder("it was", "kingdom", "sea"); +res = finder.find(text()); +LOGGER.info("the result of advanced query is {}", res); + +res = Finders.filteredFinder(" was ", "many", "child").find(text()); +LOGGER.info("the result of filtered query is {}", res); + +private static String text() { + return + "It was many and many a year ago,\n" + + "In a kingdom by the sea,\n" + + "That a maiden there lived whom you may know\n" + + "By the name of ANNABEL LEE;\n" + + "And this maiden she lived with no other thought\n" + + "Than to love and be loved by me.\n" + + "I was a child and she was a child,\n" + + "In this kingdom by the sea;\n" + + "But we loved with a love that was more than love-\n" + + "I and my Annabel Lee;\n" + + "With a love that the winged seraphs of heaven\n" + + "Coveted her and me."; + } +``` + +**程序输出:** + +```java +the result of expanded(or) query[[many, Annabel]] is [It was many and many a year ago,, By the name of ANNABEL LEE;, I and my Annabel Lee;] +the result of specialized(and) query[[Annabel, my]] is [I and my Annabel Lee;] +the result of advanced query is [It was many and many a year ago,] +the result of filtered query is [But we loved with a love that was more than love-] +``` + +现在我们可以设计我们的应用程序,使其具有查询查找功能`expandedFinder`, `specializedFinder`, `advancedFinder`, `filteredFinder`,这些功能均派生自`contains`, `or`, `not`, `and`。 + + +## 类图 +![alt text](./etc/combinator.urm.png "Combinator class diagram") + +## 适用性 +在以下情况下使用组合器模式: + +- 您可以从更简单的值创建更复杂的值,但具有相同的类型(它们的组合) + +## 好处 + +- 从开发人员的角度来看,API 由领域中的术语组成。 +- 组合阶段和应用阶段之间有明显的区别。 +- 首先构造一个实例,然后执行它。 +- 这使得该模式适用于并行环境。 + + +## 现实世界的例子 + +- java.util.function.Function#compose +- java.util.function.Function#andThen + +## 鸣谢 + +- [Example for java](https://gtrefs.github.io/code/combinator-pattern/) +- [Combinator pattern](https://wiki.haskell.org/Combinator_pattern) +- [Combinatory logic](https://wiki.haskell.org/Combinatory_logic) diff --git a/localization/zh/combinator/etc/combinator.urm.png b/localization/zh/combinator/etc/combinator.urm.png new file mode 100644 index 0000000000000000000000000000000000000000..80fdd36340bbacbbfd19ed0a4aa70c259b53c397 GIT binary patch literal 22657 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 监视器模式用于强制对数据进行单线程访问。 一次只允许一个线程在监视器对象内执行代码。 + +维基百科说 + +> 在并发编程(也称为并行编程)中,监视器是一种同步构造,它允许线程具有互斥性和等待(阻止)特定条件变为假的能力。 监视器还具有向其他线程发出信号通知其条件已满足的机制。 + +**程序示例** + +考虑有一家银行通过转账方式将钱从一个帐户转移到另一个帐户。 它是`同步`意味着只有一个线程可以访问此方法,因为如果许多线程访问它并在同一时间将资金从一个帐户转移到另一个帐户,则余额会发生变化! + +``` +class Bank { + + private int[] accounts; + Logger logger; + + public Bank(int accountNum, int baseAmount, Logger logger) { + this.logger = logger; + accounts = new int[accountNum]; + Arrays.fill(accounts, baseAmount); + } + + public synchronized void transfer(int accountA, int accountB, int amount) { + if (accounts[accountA] >= amount) { + accounts[accountB] += amount; + accounts[accountA] -= amount; + logger.info("Transferred from account :" + accountA + " to account :" + accountB + " , amount :" + amount + " . balance :" + getBalance()); + } + } +``` + +getBalance 始终返回总金额,并且每次转账后总金额应相同 + +``` + private synchronized int getBalance() { + int balance = 0; + for (int account : accounts) { + balance += account; + } + return balance; + } + } +``` + +## 类图 +![alt text](./etc/monitor.urm.png "Monitor class diagram") + +## 适用性 + +监视器设计模式应该用于具有需要由多个线程或进程同时访问和操作的共享资源的情况。 此模式在需要同步以防止竞争条件、数据损坏和不一致状态的情况下特别有用。 以下是您应该考虑使用监视器模式的一些情况: + +1. **共享数据**:当您的应用程序涉及需要由多个线程访问和更新的共享数据结构、变量或资源时。 监视器确保一次只有一个线程可以访问共享资源,从而防止冲突并确保数据一致性。 + +2. **关键部分**:当您有代码的关键部分一次只需要由一个线程执行时。 关键部分是操作共享资源的代码部分,并发访问可能会导致问题。 监视器有助于确保在任何给定时间只有一个线程可以执行关键部分。 + +3. **线程安全**:当您需要确保线程安全而不是仅仅依赖锁和信号量等低级同步机制时。 监视器提供了封装同步和资源管理的更高级别的抽象。 + +4. **等待和发信号**:当您遇到线程需要等待满足某些条件才能继续操作时。 监视器通常包含线程等待特定条件以及其他线程在满足条件时通知它们的机制。 + +5. **死锁预防**:当您希望通过提供结构化方式来获取和释放共享资源上的锁来防止死锁时。 监视器通过确保资源访问得到良好管理来帮助避免常见的死锁情况。 + +6. **并发数据结构**:当您实现并发数据结构(例如队列、堆栈或哈希表)时,多个线程需要操作该结构,同时保持其完整性。 + +7. **资源共享**:当多个线程需要共享有限的资源时,例如连接数据库或访问网络套接字。 监视器可以帮助以受控方式管理这些资源的分配和释放。 + +8. **改进可维护性**:当您想要将同步逻辑和共享资源管理封装在单个对象中时,改进代码组织并使并发相关代码更容易推理。 + +但是,需要注意的是,监视器模式可能并不最适合所有并发场景。 在某些情况下,其他同步机制(例如锁、信号量或并发数据结构)可能更合适。 此外,现代编程语言和框架通常提供更高级别的并发结构,抽象出低级别同步的复杂性。 + +在应用监视器模式之前,建议彻底分析应用程序的并发需求,并选择最适合您需求的同步方法,同时考虑性能、复杂性和可用语言功能等因素。 + +## 相关模式 + +* Active object +* Double-checked locking diff --git a/localization/zh/monitor/etc/monitor.urm.png b/localization/zh/monitor/etc/monitor.urm.png new file mode 100644 index 0000000000000000000000000000000000000000..c00e70e3fd12cf01a074ecdf6cec3cccc79af721 GIT binary patch literal 10483 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 R2w>VEX>s}2-$eEO{tq4%7h(Va literal 0 HcmV?d00001