added pattern Chain Of Responsibilities

This commit is contained in:
evitwilly
2022-09-23 11:32:54 +03:00
parent 60334270fb
commit 2a7745e052
11 changed files with 114 additions and 2 deletions

View File

@ -33,9 +33,10 @@ Content:
* [Singleton](/src/main/kotlin/design_patterns/Singleton.kt)
* [Strategy](/src/main/kotlin/design_patterns/Strategy.kt)
* [Observer](/src/main/kotlin/design_patterns/Observer.kt)
* [Dependency Injection](/src/main/kotlin/design_patterns/Dependency%20%20Injection.kt)
* [Dependency Injection](/src/main/kotlin/design_patterns/Dependency%20Injection.kt)
* [Adapter](/src/main/kotlin/design_patterns/Adapter.kt)
* [Memento](/src/main/kotlin/design_patterns/Memento.kt)
* [Chain Of Responsibilities](/src/main/kotlin/design_patterns/Chain%20Of%20Responsibilities.kt)
2. package <code>structures</code> - data structure
* [Binary tree](/src/main/kotlin/structures/BinaryTree.kt)

View File

@ -31,9 +31,10 @@
* [Singleton](/src/main/kotlin/design_patterns/Singleton.kt)
* [Strategy](/src/main/kotlin/design_patterns/Strategy.kt)
* [Observer](/src/main/kotlin/design_patterns/Observer.kt)
* [Dependency Injection](/src/main/kotlin/design_patterns/Dependency%20%20Injection.kt)
* [Dependency Injection](/src/main/kotlin/design_patterns/Dependency%20Injection.kt)
* [Adapter](/src/main/kotlin/design_patterns/Adapter.kt)
* [Memento](/src/main/kotlin/design_patterns/Memento.kt)
* [Chain Of Responsibilities](/src/main/kotlin/design_patterns/Chain%20Of%20Responsibilities.kt)
2. пакет <code>ru.structures</code> - структуры данных
* [Бинарное дерево](/src/main/kotlin/structures/BinaryTree.kt)

View File

@ -1,6 +1,7 @@
package design_patterns
/**
*
* pattern: Visitor
*
* description: it's a behavioral pattern that allows you to add a new operation

View File

@ -0,0 +1,68 @@
package design_patterns
/**
*
* pattern: Chain of responsibility
*
* description: a design pattern consisting of “a source of command objects and a series of processing objects”.
* Each processing object in the chain is responsible for a certain type of command, and the processing is done,
* it forwards the command to the next processor in the chain.
*
*/
enum class BlockFactor {
ONE, TWO, THREE
}
/**
*
* I decided to give an analogy from the Minecraft game.
* In this game there are blocks that can be broken with a stone pickaxe, iron and diamond.
* For example: diamond may mine by iron and diamond pickaxes unlike cobblestone, which is mined by any
*
*/
abstract class Block(private val factor: BlockFactor) {
fun mayMine(factor: BlockFactor) = this.factor.ordinal <= factor.ordinal
}
/**
*
* blocks from the game
*
*/
class StoneBlock: Block(BlockFactor.ONE)
class DiamondBlock: Block(BlockFactor.TWO)
class ObsidianBlock: Block(BlockFactor.THREE)
abstract class Pickaxe(private val factor: BlockFactor) {
private var nextPickaxe: Pickaxe? = null
fun changeNextPickaxe(pickaxe: Pickaxe) {
this.nextPickaxe = pickaxe
}
/**
*
* we mine the block, if it doesn't work, we take another pickaxe, if there is one
*
* @return return true if a pickaxe can mine
*/
fun mine(block: Block): Boolean =
if (block.mayMine(factor)) {
true
} else {
nextPickaxe?.mine(block) ?: false
}
}
/**
*
* pickaxes from the game
*
*/
class StonePickaxe: Pickaxe(BlockFactor.ONE)
class IronPickaxe: Pickaxe(BlockFactor.TWO)
class DiamondPickaxe: Pickaxe(BlockFactor.THREE)

View File

@ -0,0 +1,41 @@
package design_patterns
import org.junit.Test
import org.junit.jupiter.api.Assertions
class ChainOfResponsibilitiesTest {
@Test
fun test_when_we_have_only_stone_pickaxe() {
val pickaxe = StonePickaxe()
Assertions.assertEquals(true, pickaxe.mine(StoneBlock()))
Assertions.assertEquals(false, pickaxe.mine(DiamondBlock()))
Assertions.assertEquals(false, pickaxe.mine(ObsidianBlock()))
}
@Test
fun test_when_we_have_stone_and_iron_pickaxes() {
val pickaxe = StonePickaxe()
pickaxe.changeNextPickaxe(IronPickaxe())
Assertions.assertEquals(true, pickaxe.mine(StoneBlock()))
Assertions.assertEquals(true, pickaxe.mine(DiamondBlock()))
Assertions.assertEquals(false, pickaxe.mine(ObsidianBlock()))
}
@Test
fun test_when_we_have_all_three_pickaxes() {
val pickaxe = StonePickaxe()
val ironPickaxe = IronPickaxe().apply {
changeNextPickaxe(DiamondPickaxe())
}
pickaxe.changeNextPickaxe(ironPickaxe)
Assertions.assertEquals(true, pickaxe.mine(StoneBlock()))
Assertions.assertEquals(true, pickaxe.mine(DiamondBlock()))
Assertions.assertEquals(true, pickaxe.mine(ObsidianBlock()))
}
}