Compare commits

..

7 Commits

Author SHA1 Message Date
be52efc49b docs: update .all-contributorsrc [skip ci] 2020-12-07 18:24:47 +00:00
e47a24643a docs: update README.md [skip ci] 2020-12-07 18:24:46 +00:00
a118a995ec docs: add omk13 as a contributor (#1611)
* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2020-12-07 19:58:05 +02:00
759c99d078 JUnit4 to JUnit5 (#1589)
* Getting @Test from JUnit5 instead of JUnit4

* Changed FixedStepGameLoopTest.java imports and tests to JUnit5

* JUnit4 to JUnit5

* JUnit4 to JUnit5

* JUnit4 to JUnit5

* JUnit4 to JUnit5
2020-12-07 19:55:13 +02:00
e9f73bcf0b Translation zh (#1610)
* add state and callback pattern

* add command and template-method pattern

* add iterator pattern

* add bridege and DI pattern

* fix issue #1600

Co-authored-by: Mike <admin@xiaod.info>
Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
2020-12-06 16:13:48 +02:00
29ceac2fb0 Update README.md (#1592) 2020-12-05 10:56:00 +02:00
7255c2c5e7 docs: add Anurag870 as a contributor (#1609)
* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

* Update README.md

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
Co-authored-by: Ilkka Seppälä <ilkka.seppala@gofore.com>
Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
2020-12-05 10:50:09 +02:00
12 changed files with 372 additions and 51 deletions

View File

@ -1296,6 +1296,24 @@
"contributions": [
"doc"
]
},
{
"login": "omk13",
"name": "Omar Karazoun",
"avatar_url": "https://avatars0.githubusercontent.com/u/59054172?v=4",
"profile": "https://github.com/omk13",
"contributions": [
"code"
]
},
{
"login": "jeff303",
"name": "Jeff Evans",
"avatar_url": "https://avatars0.githubusercontent.com/u/3521562?v=4",
"profile": "https://github.com/jeff303",
"contributions": [
"code"
]
}
],
"contributorsPerLine": 4,

View File

@ -10,7 +10,7 @@
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=coverage)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns)
[![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-142-orange.svg?style=flat-square)](#contributors-)
[![All Contributors](https://img.shields.io/badge/all_contributors-144-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->
# Introduction
@ -282,6 +282,8 @@ This project is licensed under the terms of the MIT license.
<tr>
<td align="center"><a href="https://ibrahimalii.github.io/"><img src="https://avatars2.githubusercontent.com/u/21141301?v=4" width="100px;" alt=""/><br /><sub><b>Ibrahim ali abdelghany</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/pulls?q=is%3Apr+reviewed-by%3AibrahimAlii" title="Reviewed Pull Requests">👀</a></td>
<td align="center"><a href="https://github.com/gkulkarni2020"><img src="https://avatars3.githubusercontent.com/u/5161548?v=4" width="100px;" alt=""/><br /><sub><b>Girish Kulkarni</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=gkulkarni2020" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/omk13"><img src="https://avatars0.githubusercontent.com/u/59054172?v=4" width="100px;" alt=""/><br /><sub><b>Omar Karazoun</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=omk13" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/jeff303"><img src="https://avatars0.githubusercontent.com/u/3521562?v=4" width="100px;" alt=""/><br /><sub><b>Jeff Evans</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=jeff303" title="Code">💻</a></td>
</tr>
</table>

View File

@ -98,7 +98,7 @@ Now on the client code we can create different types of cars using the factory c
var car1 = CarsFactory.getCar(CarType.FORD);
var car2 = CarsFactory.getCar(CarType.FERRARI);
LOGGER.info(car1.getDescription());
LOGGER.info(car2.getDescription());;
LOGGER.info(car2.getDescription());
```
Program output:

View File

@ -23,7 +23,7 @@
package com.iluwatar.gameloop;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;

View File

@ -23,10 +23,11 @@
package com.iluwatar.gameloop;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
/**
* FixedStepGameLoop unit test class.
@ -35,12 +36,12 @@ public class FixedStepGameLoopTest {
private FixedStepGameLoop gameLoop;
@Before
@BeforeEach
public void setup() {
gameLoop = new FixedStepGameLoop();
}
@After
@AfterEach
public void tearDown() {
gameLoop = null;
}
@ -48,7 +49,7 @@ public class FixedStepGameLoopTest {
@Test
public void testUpdate() {
gameLoop.update();
Assert.assertEquals(0.01f, gameLoop.controller.getBulletPosition(), 0);
assertEquals(0.01f, gameLoop.controller.getBulletPosition(), 0);
}
}

View File

@ -23,10 +23,10 @@
package com.iluwatar.gameloop;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
/**
* FrameBasedGameLoop unit test class.
@ -35,19 +35,19 @@ public class FrameBasedGameLoopTest {
private FrameBasedGameLoop gameLoop;
@Before
@BeforeEach
public void setup() {
gameLoop = new FrameBasedGameLoop();
}
@After
@AfterEach
public void tearDown() {
gameLoop = null;
}
@Test
@org.junit.jupiter.api.Test
public void testUpdate() {
gameLoop.update();
Assert.assertEquals(0.5f, gameLoop.controller.getBulletPosition(), 0);
assertEquals(0.5f, gameLoop.controller.getBulletPosition(), 0);
}
}

View File

@ -23,34 +23,33 @@
package com.iluwatar.gameloop;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
public class GameControllerTest {
private GameController controller;
@Before
@BeforeEach
public void setup() {
controller = new GameController();
}
@After
@AfterEach
public void tearDown() {
controller = null;
}
@Test
@org.junit.jupiter.api.Test
public void testMoveBullet() {
controller.moveBullet(1.5f);
Assert.assertEquals(1.5f, controller.bullet.getPosition(), 0);
Assertions.assertEquals(1.5f, controller.bullet.getPosition(), 0);
}
@Test
@org.junit.jupiter.api.Test
public void testGetBulletPosition() {
Assert.assertEquals(controller.bullet.getPosition(), controller.getBulletPosition(), 0);
Assertions.assertEquals(controller.bullet.getPosition(), controller.getBulletPosition(), 0);
}
}

View File

@ -23,10 +23,9 @@
package com.iluwatar.gameloop;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
/**
* GameLoop unit test class.
@ -38,7 +37,7 @@ public class GameLoopTest {
/**
* Create mock implementation of GameLoop.
*/
@Before
@BeforeEach
public void setup() {
gameLoop = new GameLoop() {
@Override
@ -46,26 +45,26 @@ public class GameLoopTest {
};
}
@After
@AfterEach
public void tearDown() {
gameLoop = null;
}
@Test
@org.junit.jupiter.api.Test
public void testRun() {
gameLoop.run();
Assert.assertEquals(GameStatus.RUNNING, gameLoop.status);
Assertions.assertEquals(GameStatus.RUNNING, gameLoop.status);
}
@Test
@org.junit.jupiter.api.Test
public void testStop() {
gameLoop.stop();
Assert.assertEquals(GameStatus.STOPPED, gameLoop.status);
Assertions.assertEquals(GameStatus.STOPPED, gameLoop.status);
}
@Test
@org.junit.jupiter.api.Test
public void testIsGameRunning() {
Assert.assertFalse(gameLoop.isGameRunning());
Assertions.assertFalse(gameLoop.isGameRunning());
}
}

View File

@ -23,11 +23,9 @@
package com.iluwatar.gameloop;
import java.lang.reflect.InvocationTargetException;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
/**
* VariableStepGameLoop unit test class.
@ -36,19 +34,19 @@ public class VariableStepGameLoopTest {
private VariableStepGameLoop gameLoop;
@Before
@BeforeEach
public void setup() {
gameLoop = new VariableStepGameLoop();
}
@After
@AfterEach
public void tearDown() {
gameLoop = null;
}
@Test
@org.junit.jupiter.api.Test
public void testUpdate() {
gameLoop.update(20L);
Assert.assertEquals(0.01f, gameLoop.controller.getBulletPosition(), 0);
Assertions.assertEquals(0.01f, gameLoop.controller.getBulletPosition(), 0);
}
}

205
zh/bridge/README.md Normal file
View File

@ -0,0 +1,205 @@
---
layout: pattern
title: Bridge
folder: bridge
permalink: /patterns/bridge/
categories: Structural
tags:
- Gang of Four
---
## 又被称为
手柄/身体模式
## 目的
将抽象与其实现分离,以便二者可以独立变化。
## 解释
真实世界例子
> 考虑一下你拥有一种具有不同附魔的武器,并且应该允许将具有不同附魔的不同武器混合使用。 你会怎么做? 为每个附魔创建每种武器的多个副本,还是只是创建单独的附魔并根据需要为武器设置它? 桥接模式使您可以进行第二次操作。
通俗的说
> 桥接模式是一个更推荐组合而不是继承的模式。将实现细节从一个层次结构推送到具有单独层次结构的另一个对象。
维基百科说
> 桥接模式是软件工程中使用的一种设计模式,旨在“将抽象与其实现分离,从而使两者可以独立变化”
**程序示例**
翻译一下上面的武器示例。下面我们有武器的类层级:
```java
public interface Weapon {
void wield();
void swing();
void unwield();
Enchantment getEnchantment();
}
public class Sword implements Weapon {
private final Enchantment enchantment;
public Sword(Enchantment enchantment) {
this.enchantment = enchantment;
}
@Override
public void wield() {
LOGGER.info("The sword is wielded.");
enchantment.onActivate();
}
@Override
public void swing() {
LOGGER.info("The sword is swinged.");
enchantment.apply();
}
@Override
public void unwield() {
LOGGER.info("The sword is unwielded.");
enchantment.onDeactivate();
}
@Override
public Enchantment getEnchantment() {
return enchantment;
}
}
public class Hammer implements Weapon {
private final Enchantment enchantment;
public Hammer(Enchantment enchantment) {
this.enchantment = enchantment;
}
@Override
public void wield() {
LOGGER.info("The hammer is wielded.");
enchantment.onActivate();
}
@Override
public void swing() {
LOGGER.info("The hammer is swinged.");
enchantment.apply();
}
@Override
public void unwield() {
LOGGER.info("The hammer is unwielded.");
enchantment.onDeactivate();
}
@Override
public Enchantment getEnchantment() {
return enchantment;
}
}
```
这里是单独的附魔类结构:
```java
public interface Enchantment {
void onActivate();
void apply();
void onDeactivate();
}
public class FlyingEnchantment implements Enchantment {
@Override
public void onActivate() {
LOGGER.info("The item begins to glow faintly.");
}
@Override
public void apply() {
LOGGER.info("The item flies and strikes the enemies finally returning to owner's hand.");
}
@Override
public void onDeactivate() {
LOGGER.info("The item's glow fades.");
}
}
public class SoulEatingEnchantment implements Enchantment {
@Override
public void onActivate() {
LOGGER.info("The item spreads bloodlust.");
}
@Override
public void apply() {
LOGGER.info("The item eats the soul of enemies.");
}
@Override
public void onDeactivate() {
LOGGER.info("Bloodlust slowly disappears.");
}
}
```
这里是两种层次结构的实践:
```java
var enchantedSword = new Sword(new SoulEatingEnchantment());
enchantedSword.wield();
enchantedSword.swing();
enchantedSword.unwield();
// The sword is wielded.
// The item spreads bloodlust.
// The sword is swinged.
// The item eats the soul of enemies.
// The sword is unwielded.
// Bloodlust slowly disappears.
var hammer = new Hammer(new FlyingEnchantment());
hammer.wield();
hammer.swing();
hammer.unwield();
// The hammer is wielded.
// The item begins to glow faintly.
// The hammer is swinged.
// The item flies and strikes the enemies finally returning to owner's hand.
// The hammer is unwielded.
// The item's glow fades.
```
## 类图
![alt text](../../bridge/etc/bridge.urm.png "Bridge class diagram")
## 适用性
使用桥接模式当
* 你想永久性的避免抽象和他的实现之间的绑定。有可能是这种情况,当实现需要被选择或者在运行时切换。
* 抽象和他们的实现应该能通过写子类来扩展。这种情况下,桥接模式让你可以组合不同的抽象和实现并独立的扩展他们。
* 对抽象的实现的改动应当不会对客户产生影响;也就是说,他们的代码不必重新编译。
* 你有种类繁多的类。这样的类层次结构表明需要将一个对象分为两部分。Rumbaugh 使用术语“嵌套归纳”来指代这种类层次结构。
* 你想在多个对象间分享一种实现可能使用引用计数这个事实应该对客户隐藏。一个简单的示例是Coplien的String类其中多个对象可以共享同一字符串表示形式
## 教程
* [Bridge Pattern Tutorial](https://www.journaldev.com/1491/bridge-design-pattern-java)
## 鸣谢
* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59)
* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b)

View File

@ -33,8 +33,6 @@ tags:
以巨魔的为例。首先我有有一个简单的巨魔,实现了巨魔接口。
程序mple. First of all we have a simple troll implementing the troll interface
```java
public interface Troll {
void attack();

View File

@ -0,0 +1,101 @@
---
layout: pattern
title: Dependency Injection
folder: dependency-injection
permalink: /patterns/dependency-injection/
categories: Creational
tags:
- Decoupling
---
## 目的
依赖注入是一种软件设计模式,其中一个或多个依赖项(或服务)被注入或通过引用传递到一个依赖对象(或客户端)中,并成为客户端状态的一部分。该模式将客户的依赖关系的创建与其自身的行为分开,这使程序设计可以松散耦合,并遵循控制反转和单一职责原则。
## 解释
真实世界例子
> 老巫师喜欢不时地装满烟斗抽烟。 但是,他不想只依赖一个烟草品牌,而是希望能够互换使用它们。
通俗的说
> 依赖注入将客户端依赖的创建与其自身行为分开。
维基百科说
> 在软件工程中,依赖注入是一种对象接收其依赖的其他对象的技术。 这些其他对象称为依赖项。
**程序示例**
先介绍一下烟草接口和具体的品牌。
```java
public abstract class Tobacco {
private static final Logger LOGGER = LoggerFactory.getLogger(Tobacco.class);
public void smoke(Wizard wizard) {
LOGGER.info("{} smoking {}", wizard.getClass().getSimpleName(),
this.getClass().getSimpleName());
}
}
public class SecondBreakfastTobacco extends Tobacco {
}
public class RivendellTobacco extends Tobacco {
}
public class OldTobyTobacco extends Tobacco {
}
```
下面是老巫师的类的层次结构。
```java
public interface Wizard {
void smoke();
}
public class AdvancedWizard implements Wizard {
private final Tobacco tobacco;
public AdvancedWizard(Tobacco tobacco) {
this.tobacco = tobacco;
}
@Override
public void smoke() {
tobacco.smoke(this);
}
}
```
最后我们可以看到给老巫师任意品牌的烟草是多么的简单。
```java
var advancedWizard = new AdvancedWizard(new SecondBreakfastTobacco());
advancedWizard.smoke();
```
## 类图
![alt text](../../dependency-injection/etc/dependency-injection.png "Dependency Injection")
## 适用性
使用依赖注入当:
- 当你需要从对象中移除掉具体的实现内容时
* 使用模拟对象或存根隔离地启用类的单元测试
## 鸣谢
* [Dependency Injection Principles, Practices, and Patterns](https://www.amazon.com/gp/product/161729473X/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=161729473X&linkId=57079257a5c7d33755493802f3b884bd)
* [Clean Code: A Handbook of Agile Software Craftsmanship](https://www.amazon.com/gp/product/0132350882/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0132350882&linkCode=as2&tag=javadesignpat-20&linkId=2c390d89cc9e61c01b9e7005c7842871)
* [Java 9 Dependency Injection: Write loosely coupled code with Spring 5 and Guice](https://www.amazon.com/gp/product/1788296257/ref=as_li_tl?ie=UTF8&tag=javadesignpat-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=1788296257&linkId=4e9137a3bf722a8b5b156cce1eec0fc1)
* [Google Guice Tutorial: Open source Java based dependency injection framework](https://www.amazon.com/gp/product/B083P7DZ8M/ref=as_li_tl?ie=UTF8&tag=javadesignpat-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=B083P7DZ8M&linkId=04f0f902c877921e45215b624a124bfe)