Questions tagged «design-patterns»

设计模式是解决软件设计中常见问题的通用可重用解决方案。

3
当我们可以在C ++中将接口用于相同目的时,PImpl模式有什么意义?
我看到很多在C ++中使用PImpl惯用语的源代码。我假设它的目的是隐藏私有数据/类型/实现,因此它可以消除依赖关系,然后减少编译时间和标头包含问题。 但是C ++中的interface / pure-abstract类也具有此功能,它们也可以用于隐藏数据/类型/实现。为了让调用者在创建对象时只看到接口,我们可以在接口的头中声明一个工厂方法。 比较为: 费用: 接口方式的成本较低,因为您甚至不需要重复公共包装器函数的实现void Bar::doWork() { return m_impl->doWork(); },您只需要在接口中定义签名即可。 很好理解: 每个C ++开发人员都可以更好地理解接口技术。 性能: 接口方式的性能并不比PImpl成语差,两者都需要额外的内存访问。我认为性能是一样的。 以下是伪代码来说明我的问题: // Forward declaration can help you avoid include BarImpl header, and those included in BarImpl header. class BarImpl; class Bar { public: // public functions void doWork(); private: // You …


7
为什么链式装订工非常规?
在bean上实现链接非常方便:无需重载构造函数,大型构造函数,工厂,并提高了可读性。我想不出任何弊端,除非您希望对象是不可变的,在这种情况下,它就不会有任何设置方法。那么,这不是OOP约定的原因吗? public class DTO { private String foo; private String bar; public String getFoo() { return foo; } public String getBar() { return bar; } public DTO setFoo(String foo) { this.foo = foo; return this; } public DTO setBar(String bar) { this.bar = bar; return this; } } //...// DTO …

5
建设者模式:什么时候失败?
在实施“构建器模式”时,我经常感到困惑于何时让构建失败,甚至每隔几天我就此采取不同的立场。 首先来一些解释: 随着早期的失败我的意思是建立一个对象应为无效参数传入,一旦失败,所以里面的SomeObjectBuilder。 有了失败的晚期我的意思是,只有建立一个对象可以在失败build()的是隐含调用对象的构造函数来建立呼叫。 然后是一些参数: 支持延迟失败:构建器类不应只不过是仅包含值的类。而且,它导致更少的代码重复。 支持尽早失败:软件编程中的一种通用方法是您希望尽早发现问题,因此,最合乎逻辑的检查位置是在构建器类的“构造器”,“设置器”中,最后是在build方法中。 关于此的普遍共识是什么?

4
异常传播:何时应捕获异常?
MethodA调用MethodB,然后依次调用MethodC。 在MethodB或MethodC中没有异常处理。但是在MethodA中有异常处理。 在MethodC中发生异常。 现在,该异常正在冒泡到MethodA,该方法可以适当地对其进行处理。 这有什么问题? 在我看来,在某个时候调用者将执行MethodB或MethodC,并且当这些方法中确实发生异常时,从这些方法内部处理异常中可以获得什么,这实际上只是一个try / catch / finally块,而不仅仅是让他们冒泡给被呼叫者? 围绕异常处理的陈述或共识是,仅在执行不能继续执行时抛出该异常。我明白了。但是,为什么不在链的更深处捕获异常,而不是让try / catch块一直向下传播。 当您需要释放资源时,我会理解的。完全是另一回事。

11
错误变量是反模式还是好的设计?
为了处理不应停止执行的几种可能的错误,我有一个error变量,客户端可以检查并使用该变量引发异常。这是反模式吗?有没有更好的方法来解决这个问题?有关此操作的示例,您可以查看PHP的mysqli API。假定正确处理了可见性问题(访问器,公共和私有范围,是类中的变量还是全局变量?)。

2
NaN拳击的目的是什么?
阅读21世纪C时,我到达了第6章的“用NaNs标记异常数值”一节,其中解释了使用尾数中的位来存储一些任意位模式,将它们用作标记或指针的方法(书中提到WebKit使用了这种技术)。 我不确定我是否了解这种技术的效用,我认为这是一种hack(它依赖于硬件而不是NaN中尾数的值),但是来自我不习惯的Java背景C的粗糙度 这是在NaN中设置和读取标记的代码段 #include <stdio.h> #include <math.h> //isnan double ref; double set_na(){ if (!ref) { ref=0/0.; char *cr = (char *)(&ref); cr[2]='a'; } return ref; } int is_na(double in){ if (!ref) return 0; //set_na was never called==>no NAs yet. char *cc = (char *)(&in); char *cr = (char *)(&ref); for …

13
设计模式-您使用它们吗?
作为一名IT专业学生,我们的一位老师最近给了我一些有关设计模式的概述。我了解它们的用途,但某些方面仍然困扰着我。 它们是大多数程序员真正使用的吗? 说到经验,我在编程时遇到了一些麻烦,但我暂时无法解决,但是Google和一些小时的研究解决了我的问题。如果在网络中某个地方找到解决问题的方法,这是一种设计模式吗?我在用吗? 而且,您(程序员)在开始开发时是否发现自己正在寻找模式(顺便问一下,我应该在哪里寻找?)?如果是这样,那肯定是我必须开始接受的习惯。 更新:我想当我问程序员是否使用它们时,我是在问是否有问题要解决时,您会认为“哦,我应该使用该模式”。

5
MVC的劣势是什么?[关闭]
自多年前开始真正组织代码以来,我一直在使用MVC / MV *。我使用它已经很久了,以至于我什至无法想到其他任何方式来构造我的代码,而成为实习生后我做的每一项工作都是基于MVC的。 我的问题是,MVC的劣势是什么?在什么情况下,MVC对项目来说是一个错误的选择,那么(更多)正确的选择是什么?当我查找MVC替代方案时,几乎每个结果都是不同类型的MVC。 为了缩小范围,使之不会关闭,对于Web应用程序来说。我确实在不同项目的后端和前端上工作,所以我不能只说前端或后端。

3
控制器调用存储库而不是服务是不好的做法吗?
控制器调用存储库而不是服务是不好的做法吗? 解释更多: 我发现,在好的设计控制器中,可以调用服务和服务使用存储库。 但有时在控制器中,我不需要任何逻辑,只需要从db中获取并将其传递给视图即可。 而且我可以通过调用存储库来做到这一点-无需调用服务-这是不好的做法吗?

2
性能是不完全使用SignalR(网络套接字)来代替传统REST API的唯一原因吗?
我曾SignalR在多个项目中实现实时消息传递功能。它似乎工作可靠,并且非常易于学习使用。 至少对我来说,诱惑是放弃开发Web API服务,并将其SignalR用于一切。 我觉得这可以通过深思熟虑的设计来实现,如果可以的话,这意味着将需要更少的客户端代码。更重要的是,这将意味着将有一个单一的服务接口,而不是一个分离的接口,并且在最坏的情况下,可以将其连接起来而无需考虑何时渲染事物,等等。 因此,我想知道: 除了性能之外,还有其他原因不使用SignalR代替所有Web服务吗? SignalR的性能是否足以引起人们的注意? 能够将服务器端对象和服务定义转换为客户端服务访问代码而不用愚蠢的东西一直是我的梦想node.js。例如,如果我定义了一个有趣的对象InterestingObject以及该对象的服务,CRUD则InterestingObjectService可以定义到该服务的标准URL路由-例如“ / {serviceName} / {methodName}”,但是我仍然需要编写客户端代码才能访问服务。由于对象将被从客户端传递到服务器和背部,没有实际的原因有在客户端代码中显式定义对象,也无需显式定义执行CRUD操作的路由。我觉得应该有一种标准化所有方法的方法,这样就可以在假定服务访问从客户端到服务器再到服务器的工作透明的前提下编写客户端,就像我在编写WinForms或Java时一样Applet或Native App或您拥有的东西。 如果SignalR足以代替传统的Web服务使用,则它可能是实现此目的的可行方法。SignalR已经包含使集线器像我描述的服务那样工作的功能,因此我可以定义一个通用基础(CRUD)服务,该服务可以开箱即用地提供所有这些功能。然后,我几乎可以认为服务访问是理所当然的,这使我免去了重新编写代码以访问约定可以访问的内容的烦恼-更重要的是,我不得不花时间编写代码来定义如何对其进行更新。 DOM。 阅读我的编辑后,我觉得这可能有点荒谬,所以请随时问我是否对我的想法有疑问。基本上,我希望服务访问尽可能透明。

7
什么时候进行事件轮询比使用观察者模式更好?
在某些情况下,对事件进行轮询是否比使用观察者模式更好?我担心使用轮询,并且只有在有人给我一个好的情况下才会开始使用它。我能想到的就是观察者模式比轮询更好。考虑这种情况: 您正在编写汽车模拟器。汽车是一个对象。汽车启动后,您要播放“ vroom vroom”声音片段。 您可以通过两种方式对此进行建模: 轮询:每秒轮询一次汽车对象,以查看其是否打开。打开时,播放声音片段。 观察者模式:将汽车设为观察者模式的主题。当它本身打开时,让它向所有观察者发布“ on”事件。创建一个新的声音对象来聆听汽车。让它实现播放声音片段的“ on”回调。 在这种情况下,我认为观察者模式会获胜。首先,轮询是处理器密集型的。其次,汽车启动时,声音片段不会立即触发。由于轮询周期的原因,最多可能有1秒的间隔。

3
什么是帮手?是设计模式吗?是算法吗?
也许有点tongue之以鼻,但由于我无法在Google的任何地方找到此答案,因此请确保Software Engineering拥有以下答案: 什么是帮手? 我已经看到该名称在每个地方都被使用(模块名称,类名称,方法名称),好像语义是深刻而有意义的,但是在计算机科学的背景下(尽管我没有学位),我从未在任何地方看到描述或定义! 是设计模式吗?是算法吗?我曾经在一个程序中工作过,在该程序中,模块和类都被称为somethingsomethinghelper(其中某些东西也是相当通用的),然后我立即将其重命名为对我来说有意义的东西,但是我感觉好像在这里丢失了一些东西!

1
工厂模式和抽象工厂之间有什么区别?
终于开始认真尝试学习一些基本模式(在职业生涯的后期,但这是一个不同的故事),我试图弄清Factory Pattern和Abstract Factory之间的区别。 这两种模式之间的主要区别是什么? 我知道Factory方法是通过继承创建对象的,而Abstract Factory是通过对象组合来创建的,但是从实际的角度来看,我仍然很难准确地看到它们各自的工作方式。

6
为什么要避免Java继承“扩展”
詹姆斯·戈斯林说 “您应该尽可能避免实现继承。” 而是使用接口继承。 但为什么?如何避免使用关键字“ extends”继承对象的结构,同时使我们的代码面向对象? 有人可以在“在书店订购书”的情况下,提供一个面向对象的示例来说明此概念吗?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.