Skip to content

Commit

Permalink
wip: adding Command pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Jonathan committed Jul 14, 2024
1 parent ea2ecdb commit a96ae67
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 19 deletions.
8 changes: 4 additions & 4 deletions __tests__/behavioral/ProcessChain.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ import {
} from 'vitest'

import {
ProcessChain,
RequestChain,
} from '@/index'

type Data = {
prop: number
}

class ProcessableChain extends ProcessChain<Data> {
class ProcessableChain extends RequestChain<Data> {
isProcessable(data: Data): boolean {
return 'prop' in data
}
Expand All @@ -54,7 +54,7 @@ class ProcessableChain extends ProcessChain<Data> {
}
}

class UnprocessableChain extends ProcessChain<Data> {
class UnprocessableChain extends RequestChain<Data> {
isProcessable(data: Data): boolean {
return !('prop' in data)
}
Expand All @@ -64,7 +64,7 @@ class UnprocessableChain extends ProcessChain<Data> {
}
}

describe('ProcessChain', () => {
describe('RequestChain', () => {
it('count the links in the chain', () => {
const a = new ProcessableChain()
const b = new ProcessableChain()
Expand Down
69 changes: 69 additions & 0 deletions src/behavioral/Command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/**
* BSD 3-Clause License
*
* Copyright © 2023, Daniel Jonathan <daniel at cosmicmind dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import {
Optional,
} from '@cosmicmind/foundationjs'

/**
* @module Command
*/

export type Command = {
/**
* Executes the method.
*
* @return {void} Returns nothing.
*/
execute(): void
}

export type Operable = {
execute(command: Command): void
}

export class Operation implements Operable {
protected commands: Command[]

constructor() {
this.commands = []
}

execute(command: Command): void {
command.execute()
this.commands.push(command)
}

pop(): Optional<Command> {
return this.commands.pop()
}
}
24 changes: 10 additions & 14 deletions src/behavioral/ProcessChain.ts → src/behavioral/RequestChain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,20 @@
*/

/**
* @module ProcessChain
* @module RequestChain
*/

import {
Nullable,
Optional,
} from '@cosmicmind/foundationjs'

export type Chainable<T> = {
/**
* Retrieves the next value in the chain.
*
* @return {Nullable<Chainable<T>>} The next value in the chain, or null if there is none.
* @return {Optional<Chainable<T>>} The next value in the chain, or undefined if there is none.
*/
get next(): Nullable<Chainable<T>>
get next(): Optional<Chainable<T>>

/**
* Executes the method with the given arguments.
Expand All @@ -63,20 +63,16 @@ export type Chainable<T> = {
isProcessable(...args: T[]): void
}

export abstract class ProcessChain<T> implements Chainable<T> {
protected _next?: Nullable<Chainable<T>>
export abstract class RequestChain<T> implements Chainable<T> {
protected _next: Optional<Chainable<T>>

/**
* Retrieves the next item in the chain.
*
* @returns {Nullable<Chainable<T>>} The next item in the chain, or null if there isn't a next item.
* @returns {Optional<Chainable<T>>} The next item in the chain, or undefined if there isn't a next item.
*/
get next(): Nullable<Chainable<T>> {
return this._next || null
}

constructor() {
this._next = null
get next(): Optional<Chainable<T>> {
return this._next
}

/**
Expand All @@ -95,7 +91,7 @@ export abstract class ProcessChain<T> implements Chainable<T> {
* @returns {void}
*/
clear(): void {
this._next = null
this._next = undefined
}

/**
Expand Down
3 changes: 2 additions & 1 deletion src/behavioral/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

export * from '@/behavioral/Observable'
export * from '@/behavioral/Observable'
export * from '@/behavioral/Plugin'
export * from '@/behavioral/ProcessChain'
export * from '@/behavioral/RequestChain'

0 comments on commit a96ae67

Please sign in to comment.