# 针对复杂应用的设计模式
这一章主要介绍了Monad。我们目前可以把Monad仅仅当作一个容器
# 基础Monad
class Wrapper{
constructor(value){
this._value = value;
}
static of(val){
return new Wrapper(val);
}
// 映射出新的monad
map(f){
return Wrapper.of(f(this._value))
}
// 处理多层monad嵌套问题,只保留一层包装
join(){
if(this.value instanceof Wrapper){
return this.value.join();
}else{
return this;
}
}
}
# Maybe Monad 处理null
class Maybe{
static just(a){
return new Just(a);
}
static nothing(){
return new Nothing();
}
// 空值用Nothing包裹 非空用Just包裹
static fromNullable(a){
return a !== null?this.just(a):this.nothing();
}
static of(a){
return this.just(a);
}
get isJust(){
return false;
}
get isNothing(){
return false;
}
}
class Just extends Maybe{
constructor(value){
super();
this._value = value;
}
get isJust(){
return true;
}
get value(){
return this._value;
}
map(f){
return Mayber.of(f(this._value))
}
getOrElse(){
return this._value;
}
}
class Nothing extends Maybe{
// 对Nothing做map 返回一个Nothing
map(f){
return this;
}
getOrElse(other){
return other;
}
get value(){
throw new TypeError("Can't extract value of nothing")
}
get isNothing(){
return true;
}
}
# Either Monad 处理异常
class Either {
constructor(value){
this._value = value;
}
static left(a){
return new Left(a);
}
static Right(a){
return new Right(a);
}
static of(a){
return new Right(a);
}
}
// Left是对异常的包裹
class Left extends Either{
map(){
return this;
}
get value(){
throw new TypeError("Can't extract the value of Left");
}
getOrElse(other){
return other
}
// orElse 方法仅将函数f应用到Left上,不应用到Right上
orElse(f){
return f(this._value)
}
}
// Right包含一个成功的值
class Right extends Either{
map(f){
return Either.of(f(this._value))
}
get value(){
return this._value;
}
getOrElse(){
return this._value;
}
orElse(){
return this;
}
}
# IO Monad 处理IO
class IO{
constructor(effect){
if(typeof effect !== 'function'){
throw 'IO Usage: function required';
}
this.effect = effect;
}
static from(fn){
return new IO(fn);
}
// 关键一步 和其他IO操作联合构成新的IO Monad
map(fn){
return new IO(()=>{
return fn(this.effect())
});
}
// 所有IO操作 一次完成
run(){
return this.effect();
}
}