让我们假设我们有Commands和CommandHandlers。每个命令一个CommandHandler。
现在,我想根据某些映射按Command对象获取CommandHandler对象的新实例。定义此类地图的最佳方法是什么? 解决方案应在代码最小化后起作用,并且应该易于重构。
目前我有我个人不喜欢的这种解决方案。
interface Command {}
class ConcreteCommand implements Command {}
class ConcreteCommand2 implements Command {}
interface CommandHandler {}
class ConcreteCommandHandler implements CommandHandler {}
class ConcreteCommand2Handler implements CommandHandler {}
const map = [ //I don't like this kind of map, any other ways?
[ConcreteCommand, ConcreteCommandHandler],
[ConcreteCommand2, ConcreteCommand2Handler]
];
function getCommandHandler(command: Command): CommandHandler {
for(let pair of map) {
if (command instanceof pair[0]) {
return new pair[1];
}
}
throw new Error('Unable to find CommandHandler.');
}
console.log( getCommandHandler(new ConcreteCommand()) ); //ConcreteCommandHandler
答案 0 :(得分:0)
JavaScript的数据类型称为Map。来自MDN:
Map对象包含键值对,并记住键的原始插入顺序。任何值(对象值和原始值)都可以用作键或值。
要使用一个:
const map = new Map()
map.set(ConcreteCommand, ConcreteCommandHandler)
const handler = new (map.get(ConcreteCommand))()
警告是您的代码无法与此配合使用,因为:
getCommandHandler(new ConcreteCommand())
每个实例将被视为唯一键。不过,您可以使用该函数本身:map.set(ConcreteCommand)
答案 1 :(得分:0)
本地Maps
对此非常有用:
const map = new Map<Command, CommandHandler>([
[ConcreteCommand, ConcreteCommandHandler],
[ConcreteCommand2, ConcreteCommand2Handler]
])
function getCommandHandler(command: Command): CommandHandler
{
if (map.has(command) == false)
throw new Error('Unable to find CommandHandler.');
return map.get(command);
}
答案 2 :(得分:0)
如果需要类型,请使用它,但是有问题
interface Cmd<T = string> { _T: T }
interface CmdHandler<T = string> { _T: T }
declare class CmdOne implements Cmd<'CmdOne'> { _T: 'CmdOne' }
declare class CmdTwo implements Cmd<'CmdTwo'> { _T: 'CmdTwo' }
declare class CmdThree implements Cmd<'CmdThree'> { _T: 'CmdThree' }
declare class CmdHandlerOne implements CmdHandler<'CmdOne'> { _T: 'CmdOne' }
declare class CmdHandlerTwo implements CmdHandler<'CmdTwo'> { _T: 'CmdTwo' }
//declare class CmdHandlerThree implements CmdHandler<'CmdThree'> { _T: 'CmdThree' }
const cmds = [
[CmdOne, CmdHandlerOne],
[CmdTwo, CmdHandlerTwo],
//[CmdThree, CmdHandlerThree],
];
export function CmdFactory<T>(cmd: Cmd<T>): CmdHandler<T> {
const handle = cmds.find(pair => cmd instanceof pair[0])[1];
return new handle as any; /// not good!
}
CmdFactory(new CmdOne)
CmdFactory(new CmdThree) /// Need error