Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Object 如何改进Typescript中的对象设计?_Object_Design Patterns_Typescript_Functional Programming - Fatal编程技术网

Object 如何改进Typescript中的对象设计?

Object 如何改进Typescript中的对象设计?,object,design-patterns,typescript,functional-programming,Object,Design Patterns,Typescript,Functional Programming,我已经在Typescript中创建了一个实现简单流(FRP)的类。现在我想用客户端功能(事件流)扩展它。为了说明我的问题,下面是一些伪代码: class Stream<T> { map<U>(f: (value: T) => U): Stream<U> { // Creates a new Stream instance that maps the values. } // Quite a few other

我已经在Typescript中创建了一个实现简单流(FRP)的类。现在我想用客户端功能(事件流)扩展它。为了说明我的问题,下面是一些伪代码:

class Stream<T> {

    map<U>(f: (value: T) => U): Stream<U> {
        // Creates a new Stream instance that maps the values.
    }

    // Quite a few other functions that return new instances.

}
ClientStream
类重写此函数以返回
ClientStream
实例。但是,编译器抱怨
ClientStream.map
返回的是
Stream
,而不是
ClientStream
。这可以通过使用石膏来“解决”,但除了丑陋之外,它还可以防止链接

显示此问题的示例代码:

class Stream {

    protected create(): Stream {
        return new Stream()
    }

    map() {
        return this.create()
    }

}

class ClientStream extends Stream {

    protected create(): ClientStream {
        return new ClientStream()
    }

    watch() {
        return this.create()
    }

}

let s = new ClientStream().map().watch()
这不会编译,因为根据编译器,从
map
返回的流不是
ClientStream
错误TS2339:类型“stream”上不存在属性“watch”。

我真的不喜欢这种模式,但我没有其他更优雅的解决方案。我想到的事情:

  • 使用构图(装饰器)。考虑到我需要代理的方法的数量,这不是一个真正的选择。我希望以后能够将方法添加到
    Stream
    ,而不必担心
    ClientStream
  • Stream
    混合到
    ClientStream
    中。或多或少,同样的问题,
    ClientStream
    必须知道将要混合的函数的签名(或者不知道?请告诉我)
  • 将这些类合并为一个类。这是万不得已的办法,
    watch
    功能与服务器无关

你有更好(更优雅)的解决方案吗?如果你有一个更接近实用风格的想法,我很乐意听到。谢谢

你想做的事叫做

在TypeScript中,这是通过
this
关键字完成的。请看一看Typescript的文档以了解。如果遵循文档,您应该能够实现您想要的:-)


实际上,只要确保在成员方法中返回
这个
,就可以了

你想做的事叫做

在TypeScript中,这是通过
this
关键字完成的。请看一看Typescript的文档以了解。如果遵循文档,您应该能够实现您想要的:-)



实际上,只要确保在成员方法中返回
这个
,就可以了

工厂方法可以是静态的吗?或者它们依赖实例数据吗?是的,它们可能是静态的。你可以像@SebastianSebald所说的那样使用
多态this types
,但是你的类是泛型的,这会使它变得更难。但我仍在努力理解你的问题。你能用一个完整的例子来更新你的代码吗?我可以粘贴到游乐场上,看看错误是什么,在哪里。我明天会这样做,提前感谢您的关注。我不理解您的示例。
newclientstream()
创建一个实例,然后调用其
map()
方法,该方法创建同一
ClientStream
类的新实例,并在该类上调用
watch()
方法,该方法创建
Stream
的新实例,但
ClientStream
扩展了
Stream
。这一切有什么意义?您有一个
ClientStream
/
Stream
实例,第一个
new ClientStream()
。工厂方法可以是静态的吗?或者它们依赖实例数据吗?是的,它们可能是静态的。你可以像@SebastianSebald所说的那样使用
多态this types
,但是你的类是泛型的,这会使它变得更难。但我仍在努力理解你的问题。你能用一个完整的例子来更新你的代码吗?我可以粘贴到游乐场上,看看错误是什么,在哪里。我明天会这样做,提前感谢您的关注。我不理解您的示例。
newclientstream()
创建一个实例,然后调用其
map()
方法,该方法创建同一
ClientStream
类的新实例,并在该类上调用
watch()
方法,该方法创建
Stream
的新实例,但
ClientStream
扩展了
Stream
。这一切有什么意义?您有一个
ClientStream
/
Stream
实例,第一个
new ClientStream()
。谢谢您的建议。我可能错了,但这不仅仅是建筑模式吗?这里涉及到可变状态,我想阻止它。额外的
.currentValue()
调用也是如此(对于构建器来说很典型)。我不确定这是否是构建器模式。我在wikipedia上查到了它,我也一样,它看起来似乎与wie类继承有关。如果我错了,请纠正我。在哪里可以看到可变状态?在typescript站点上的计算器示例中,
此值对于每次计算都会进行修改。关于构建器模式,它是一种通过几个步骤构建某些产品的模式。在我看来,这就是计算器的作用。即使它“只是”一个数字,结果仍然是通过多个步骤得到的,并且必须通过额外的方法调用(
currentValue
)从“生成器”中检索。啊,现在我明白你的意思了。我建议返回一个新实例。因此,不要
返回此
,而是
返回新流
。你想做的与RxJS非常相似,也许阅读也会有所帮助。谢谢你的建议。我可能错了,但这不仅仅是建筑模式吗?这里涉及到可变状态,我想阻止它。额外的
.currentValue()
调用也是如此(对于构建器来说很典型)。我不确定这是否是构建器模式。我在wikipedia上查到了它,我也一样,它看起来似乎与wie类继承有关。C
protected create<U>(.....): Stream<U> {
    return new Stream<U>(.....)
}
class Stream {

    protected create(): Stream {
        return new Stream()
    }

    map() {
        return this.create()
    }

}

class ClientStream extends Stream {

    protected create(): ClientStream {
        return new ClientStream()
    }

    watch() {
        return this.create()
    }

}

let s = new ClientStream().map().watch()