Design patterns 程序设计:调用方/被调用方dilema,同步/手动切换上下文
我的问题是关于程序的总体设计。 当对象a想要向对象b发送信息时,有三种可能性:Design patterns 程序设计:调用方/被调用方dilema,同步/手动切换上下文,design-patterns,asynchronous,coroutine,paradigms,Design Patterns,Asynchronous,Coroutine,Paradigms,我的问题是关于程序的总体设计。 当对象a想要向对象b发送信息时,有三种可能性: 控件位于对象a和b之外,调用a和b的公共方法: b.TakeInformation(a.getInformation()); 控件位于b的内部: 在这种情况下,b做它想做的事情,有时要求a提供信息: class A { public Information getInformatino() { // code omitted } // code omitted } class B { //
b.TakeInformation(a.getInformation());
b
做它想做的事情,有时要求a
提供信息:
class A {
public Information getInformatino() {
// code omitted
}
// code omitted
}
class B {
// code omitted
void foo() {
while (bar()) {
information = a.getInformation();
DoSomeWork(information);
}
}
}
a
的内部:a
做它想做的事情,有时它会给b它正在生成的信息:
class A {
// code omitted
void foo() {
while (bar()) {
information = produceInformation()
b.TakeInformation(information)
}
}
}
class B {
// code omitted
public void TakeInformation(information) {
// code omitted
}
}
我最感兴趣的是第四种可能性,a
和b
都是呼叫者,而它们都不是被呼叫者
在这种情况下,最简单的答案是:重写其中一个类,使其被调用
这让我不满意。例如,让我们假设有一种奇怪的流,它不允许我通过调用ReadChar()A.k.A.getInformation()方法来读取字符,但它是一个调用者,每次从输入读取字符时,它都调用b.giveInformation(character)
假设我不能重写类A,然后想象我编写了一个类B,它是某种语言的解析器。解析器B由许多函数和帮助类组成,并在代码的许多地方使用ReadChar
该问题的解决方案需要重写类B,以便由giveInformation(character)
调用它,而不是调用ReadChar()
。这将是非常痛苦和不直观的
对于这个合成示例,最优雅的解决方案是创建适配器,该适配器启动A
并存储所有字符,然后启动B
,并为其提供必要的字符读取接口
不幸的是,当类A
anbB
双向通信时,这不适用于其他场景
一般来说,如何解决这些任务
是否有一些具有非标准范例的编程语言可以解决这个问题
我想到了几种可能的解决方案或方法。它们由线程、管道、汇编语言或惰性计算的滥用组成,但它们似乎都不够好,或者我不知道如何使用它们。我将在回答中总结我的想法
感谢您的帮助。我需要的内容可以使用以下线程用伪代码重写:
class A {
// code omitted
void foo() {
while (bar()) {
information = produceInformation()
wake thread b, send it information
suspend this thread until result is received
result = received result
DoSomeWorkWithResult(result);
}
}
}
class B {
// code omitted
void foo() {
while (bar()) {
suspend this thread until information is received
information = received information
result = DoSomeWork(information);
wake thread a, send it the result
}
}
}
然而,我正在解决的任务的性质不是平行的。实际上,没有任何代码行可以同时执行。只有被切换的上下文没有并行运行。所以我怀疑使用线程是必要的。(我也不确定线程的开销会是多少。)
我可能会用线程编写代码,即使没有并行性。然而,我通常对如何解决此类通信的可能方法感兴趣。我确信它是可解的——至少在某些编程语言中是如此
在C++和汇编语言中,P>当然是一切可能的。如何使用两个堆栈并在上下文之间手动切换
在任何编程语言中,A、B都可以编译成两个可执行文件。A的标准输出可以是B的输入。通过使用命名管道,B的输出可以再次成为A的输入。(然而,它需要对象的序列化和反序列化。我认为这是不必要的。我也更喜欢一个可执行文件。)
在具有惰性计算的编程语言中,这种范式可能被滥用以解决此类任务
例如,在c中,可以在类B
中实现IEnumerator()
。当A将生成新信息时,将调用MoveNext()
。控件位于B
内部并挂起此“线程”的错觉可以通过调用yield return
来确保
这种方法的缺点是“线程”只能在其主方法中挂起。或者,同样的技巧必须重新应用于所有其他应该挂起线程的方法
也许c#中的异步方法可以某种方式用于解决此类任务。但是怎么做呢?你回答的设计很糟糕,比原来问题中的设计更糟糕。您在类B和类A之间添加了不必要的耦合 你看起来可能是这样的。在观察者模式中,类只需要通知订阅者一个操作已经执行,而不知道订阅了哪个类以及在收到通知时将执行什么