gpt4 book ai didi

javascript - 需要一些类似访客的设计模式

转载 作者:行者123 更新时间:2023-11-28 01:40:31 26 4
gpt4 key购买 nike

我会给你一个我的问题的示例,以消除逻辑复杂性,让你专注于重要部分。当然,这个例子会有点没用...

我有一个树结构,其中节点是这样的

{
path: "...",
childs : []
}

现在,我必须将从根到每个叶子的所有完整路径写入数组中。我的设计很差:

function listPaths(node) {
var result = [];

function listForNode(n, parentFullPath) {
var thisPath = parentFullPath + "/" + n.path;
result.push(thisPath);
n.childs.forEach(function (child) {
listForNode(child, thisPath);
});
}

listForNode(node, "");
return result;
}

这可能很好,但如果没有疯狂的 600 行代码测试文件,我就无法使用 Mocha 编写测试。这时候你应该问为什么。原因是真正目的的复杂性,这与我的问题无关。我的目标是拥有一些“可 mock ”的东西,因为我已经习惯了。 (Java 开发)。但我失败了。

你有什么模式可以用来解决这个问题吗?我不太擅长 JS 模式。 :/游客?制作 Y 组合器?这么多的可能性...

感谢您阅读我的文章

最佳答案

您需要记住,函数是 JavaScript 中的一等公民。

我发现你所拥有的本质上是这样的

function createVisitor(parentsAccumulatorInitialValue, parentsAccumulator){

var visitor = function myVisitor (node) {
var result;
function listForNode(n, parentsAcc) {
var thisPath = parentsAccumulator(parentsAcc, n);
result.push(thisPath);
n.childs && n.childs.forEach(function (child) {
listForNode(child, thisPath);
});
}

result = [];
listForNode(node, parentsAccumulatorInitialValue());
return result;
}
return visitor;

}

var listPaths = createVisitor(
function parentInit () {
return "";
},
function parentAcc (parentFullPath, n) {
return parentFullPath + "/" + n.path;
});

但这并不是您可以处理的唯一抽象:

function createVisitor2(
totalAccumulatorInitialValue,
totalAccumulator,
parentsAccumulatorInitialValue,
parentsAccumulator){

var visitor = function myVisitor (node) {
var total;
function listForNode(n, parentsAcc) {
var thisPath = parentsAccumulator(parentsAcc, n);
total = totalAccumulator(total, thisPath, n);
n.childs && n.childs.forEach(function (child) {
listForNode(child, thisPath);
});
}

total = totalAccumulatorInitialValue();
listForNode(node, parentsAccumulatorInitialValue());
return total;
}
return visitor;

}

var listPaths2 = createVisitor2(
function totalInit() {
return [];
},
function totalAcc(total, thisPath, n){
total.push(thisPath);
return total;
},
function parentInit () {
return "";
},
function parentAcc (parentFullPath, n) {
return parentFullPath + "/" + n.path;
});

这可能相当合理,但正如您所看到的,我已经开始难以为这些变量找到合适的名称。事实上,我想说我们的函数的名称很糟糕,因为它没有严格创建像我所知道的访问者对象那样的东西。但是,它确实有效(顺便说一句,我稍微修改了它以处理空值和空数组):

> listPaths( { path:"foo", 
childs: [{path:"bar", childs: null}, {path:"bob", childs: null}]})

["/foo", "/foo/bar", "/foo/bob"]

它可以进一步修改,这样你的树就不会严格具有相同的结构......但我们已经有 4 个参数,这不太好。如果向您的访问者创建者传递一个具有所有必要方法或值的可扩展对象,那就更好了。例如,也许(伪代码):

function createVisitor3(opts) {
//assume we've defined GetDefaults() somewhere local to createVisitor3
// as well as assume that extend is defined somewhere that copies properties
// into a new object like various previously existing libraries do.
opts = extend({}, GetDefaults(), opts);
var totalAccumulatorInitialValue = opts.totalAccumulatorInitialValue;
var totalAccumulator = opts.totalAccumulator;
var parentsAccumulatorInitialValue = opts.parentsAccumulatorInitialValue;
var parentsAccumulator = opts.parentsAccumulator;
var childrenGetter = opts.childrenGetter;
/// etc.
...
}

关于javascript - 需要一些类似访客的设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20980688/

26 4 0
文章推荐: c++ - 检查第 n 个可变参数模板参数是否属于特定类型
文章推荐: javascript - 找到包含所有
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com