JavaScript中的函式與命令模式,Java也有參考價值

banq發表於2018-10-18

這篇文章的目的並不是說一種正規化比另一種正規化更好。它只是顯示您遇到的常見模式及其同等的函式實現方法。(banq注:其實對使用Java Stream替代if/else也有參考作用)

if / else
命令正規化:

const hour = 14
let greeting

if (hour < 18) {
greeting = 'Good day';
} else {
greeting = 'Good evening';
}

函式正規化:
if語句可以被函式getGreeting替代,從而重用:

const isDay = hour => hour < 18
const getGreeting = hour => isDay(hour) ? 'Good Day' : 'Good Evening'
const greeting = getGreeting (hour)



if (無else)
命令正規化:

let name = 'joel'
if (name != null) {
name = name.toUpperCase()
}



函式正規化:
isNotnull和toUpperCase市可重用的函式:

import when from 'mojiscript/logic/when'

const isNotNull = obj => obj != null
const toUpperCase = when (isNotNull) (string => string.toUpperCase ())

const name = 'joel'
const upperName = toUpperCase (name)



陣列相加
命令正規化:

const values = [1, 2, 3]

let sum = 0
for (const x of values) {
sum = sum + x
}

函式正規化:
不將sum變成可變變數:

const values = [1, 2, 3]

const add = (x, y) => x + y
const sum = values.reduce(add)


[b]for/if[/b]

命令正規化:

const values = [1, 2, 3, 4, 5]

let evens =
for (const x of values) {
if (x % 2 === 0) {
evens.push(x)
}
}


函式正規化:
不要將evens成為可變:

import filter from 'mojiscript/list/filter'

const values = [1, 2, 3, 4, 5]

const isEven = num => num % 2 === 0
const evens = filter (isEven) (values)



提前中斷迴圈
命令正規化:

const values = [1, 2, 3]
let sum = 0
for (const x of values) {
if (x > 3) break
sum = sum + x
}


函式正規化:
使用reduceWhile,類似reduce,能接受一個predicate提早結束。

import reduceWhile from 'mojiscript/list/reduceWhile'

const add = x => y => x + y
const lte3 = num => num <= 3

const sum = reduceWhile (() => lte3) (add) (0) (values)




if / else if / else
命令正規化:

const fn = temp => {
if (temp === 0) return 'water freezes at 0°C'
else if (temp === 100) return 'water boils at 100°C'
else return `nothing special happens at ${temp}°C`
}

fn(0) //=> 'water freezes at 0°C'
fn(50) //=> 'nothing special happens at 50°C'
fn(100) //=> 'water boils at 100°C'


函式正規化:

import cond from 'mojiscript/logic/cond'
import $ from 'mojiscript/string/template'

const fn = cond([
<p class="indent">[0, 'water freezes at 0°C'],
<p class="indent">[100, 'water boils at 100°C'],
<p class="indent">[() => true, $`nothing special happens at ${0}°C`]
])

fn(0) //=> 'water freezes at 0°C'
fn(50) //=> 'nothing special happens at 50°C'
fn(100) //=> 'water boils at 100°C'



命令正規化:

class Cat {
constructor() {
this.sound = 'Meow'
}

talk() {
return this.sound
}
}

const cat = new Cat()
const talk = cat.talk

cat.talk() //=> 'Meow'
talk() //=> Error: Cannot read property 'sound' of undefined



函式正規化:

const cat = {
sound: 'Meow'
}

const dog = {
sound: 'Woof'
}

const talk = animal => animal.sound

talk (cat) //=> 'Meow'
talk (dog) //=> 'Woof'


檢查空NULL
命令正規化:

const toUpper = string => {
if (string != null) {
return string.toUpperCase()
}
}



函式正規化:
此示例將引數包裝在一個
Maybe
型別中,然後在最後將其解包。在一般FP應用程式中,可在整個應用程式使用Maybe,不需要打包和解包string。所以這比你通常看到的要冗長一些。

import S from 'sanctuary'

const toUpper = S.pipe ([
S.toMaybe,
S.map (string => string.toUpperCase ()),
S.maybeToNullable
])

// If you use `Maybe` throughout your app, this would be your `toUpper` function.
const toUpper = S.map (string => string.toUpperCase ());

相關文章