Questions tagged «design-patterns»

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

6
策略模式的优势
如果仅在if / then情况下编写代码,使用策略模式为什么有好处? 例如:我有一个TaxPayer类,它的一种方法使用不同的算法来计算税收。那么,为什么不具有if / then情况并找出在该方法中使用哪种算法而不是使用策略模式呢?另外,为什么不能只为TaxPayer类中的每个算法实现单独的方法? 另外,算法在运行时更改意味着什么?

5
否则-重复代码逻辑
老板给了我一个具有特定逻辑的项目。我必须开发一个网页,该网页必须带领导航员处理很多情况,直到他/她找到产品为止。 这是站点中导航的路径方案: 重要! 在产品页面中,导航器可以选择他想要的过滤器。 如果是A,则他/她必须通过B(然后是C)或C,然后到达产品。 如果是B,则他/她必须经过C并到达产品。 如果为C,则他/她直接到达产品。 当然,如果我从AI开始走的是最长的路,当我到达产品时,我将拥有3个有源滤波器。 到目前为止,我开发了下面的代码,效果很好。 if filter_A if filter_B filter_C() .. else .. else filter_C .. else .. else if filter_B filter_C() .. else .. else filter_C() .. else .. 我在这里问一个更专业的程序员在这种情况下会做什么。我不尊重DRY原理,我不喜欢它,我想知道开发这种逻辑的另一种方法。 我曾考虑过将代码的每个部分拆分为函数,但是在这种情况下,这是一个好主意吗?

1
何时在JavaScript中使用原型编程
我花了很多时间通过以下方式为项目开发简单的小部件: var project = project || {}; (function() { project.elements = { prop1: val1, prop2: val2 } project.method1 = function(val) { // Do this } project.method2 = function(val) { // Do that } project.init = function() { project.method1(project.elements.prop1) project.method2(project.elements.prop2) } })() project.init(); 但是我已经开始将格式更改为以下格式: function Project() { this.elements = { prop1: …

4
一流的功能是否可以代替战略模式?
该战略的设计模式通常被认为是在缺乏这些语言的一流功能的替代品。 例如,说您想将功能传递给对象。在Java中,您必须向该对象传递另一个封装了所需行为的对象。在诸如Ruby之类的语言中,您只是以匿名函数的形式传递功能本身。 但是我在考虑它,因此决定也许Strategy提供的功能比普通的匿名功能还多。 这是因为对象可以保持独立于其方法运行时间的状态。但是,匿名函数本身只能保持在函数完成执行后就不复存在的状态。 在支持一流功能的面向对象语言中,策略模式相对于使用功能是否有任何优势?

3
为什么要使用Android Fragments?
我已经阅读了有关该主题的文档和其他一些问题的主题,但我并没有真正感到信服。我看不出使用此技术的局限性。 片段现在被视为最佳实践 ; 基本上,每个活动都应该是对一个或多个片段的支持,而不是直接调用布局。 创建片段是为了: 允许Activity使用多个片段,在它们之间进行切换,重用这些单元... ==> Fragment完全依赖于ContextActivity的,因此,如果我需要可以在许多Activity中重用和处理的通用类,创建自己的自定义布局或视图...我不会在意片段会添加的这个额外的复杂性开发层。 对于平板电脑/手机,更好地处理不同分辨率==>确定,以防长时间处理,我们可以在平板电脑的“同一活动”中显示两个(或多个)片段,在手机中一个一个地显示。但是为什么我总是使用片段? 处理在片段之间导航的回调(即:如果用户已登录,则显示一个片段,否则显示另一个片段)。===>试着看看有多少bug导致了Facebook SDK登录,以了解它确实是(?)... 考虑到Android应用程序是基于活动的...在活动中添加另一个生命周期会更好地设计应用程序...我的意思是模块,方案,数据管理和连接性会得到更好的设计,因为办法。===>这是一个曾经用Fragments愿景看过Android SDK和Android Framework的人的答案。我不认为这是错误的,但是我不确定它是否会产生良好的结果。而且它真的很抽象。 ====>为什么总是使用它们会使我的生活变得复杂,编写更多代码?否则,如果它只是某些情况下的工具,那为什么是最佳实践呢?这些情况是什么?

4
在运行时将字段添加到类中-设计模式
想象一下,您的客户希望有可能在其CMS的eshop中为产品添加新属性(例如颜色)。 而不是将属性作为字段: class Car extends Product { protected String type; protected int seats; } 您可能最终会做类似的事情: class Product { protected String productName; protected Map<String, Property> properties; } class Property { protected String name; protected String value; } 也就是说,在现有系统之上创建自己的类型系统。在我看来,这可以看作是创建域特定的语言,还是不能? 这种方法是已知的设计模式吗?您会以不同的方式解决问题吗?我知道可以在运行时中添加字段的语言,但是数据库呢?您是愿意添加/更改列还是使用上图所示的内容? 感谢您的时间 :)。

4
仅关注成功或失败时返回布尔值
我经常发现自己从一个方法返回一个布尔值,该方法用于多个位置,以便将一个方法周围的所有逻辑包含在一个地方。所有(内部)调用方法都需要知道该操作是否成功。 我正在使用Python,但问题不一定特定于该语言。我只能想到两种选择 引发异常(尽管情况并不特殊),并记住在调用函数的每个位置都捕获该异常 在执行操作时返回布尔值。 这是一个非常简单的示例,演示了我在说什么。 import os class DoSomething(object): def remove_file(self, filename): try: os.remove(filename) except OSError: return False return True def process_file(self, filename): do_something() if remove_file(filename): do_something_else() 尽管它是功能性的,但我真的不喜欢这种做事的方式,它“闻起来”,有时会导致很多嵌套的if。但是,我想不出一种更简单的方法。 os.path.exists(filename)在尝试删除之前,我可以使用更多的LBYL原理并使用它,但是不能保证文件不会同时被锁定(这不太可能,但是可能),我仍然必须确定删除是否成功。 这是“可接受的”设计吗?如果不是,那么设计它的更好方法是什么?

2
我应该使用工厂方法而不是构造函数。我可以更改它并且仍然向后兼容吗?
问题 假设我有一个名为的类DataSource,它提供了ReadData一种从.mdb文件中读取数据的方法(也许还有其他方法,但为了简单起见): var source = new DataSource("myFile.mdb"); var data = source.ReadData(); 几年后,我决定.xml除了.mdb文件作为数据源之外,还希望能够支持文件。.xml和.mdb文件的“读取数据”实现完全不同。因此,如果我要从头开始设计系统,则可以这样定义: abstract class DataSource { abstract Data ReadData(); static DataSource OpenDataSource(string fileName) { // return MdbDataSource or XmlDataSource, as appropriate } } class MdbDataSource : DataSource { override Data ReadData() { /* implementation 1 */ } } class XmlDataSource …

5
一种从方法返回多个返回值的方法:将方法放入表示返回值的类中。这是一个好的设计吗?
我需要从一个方法返回2个值。我的方法如下: 创建一个具有2个字段的内部类,这些字段将用于保留这2个值 将方法放在该类中 实例化该类并调用该方法。 该方法中唯一要更改的是,最后它将为实例的字段分配这两个值。然后,我可以通过引用该对象的字段来解决这些值。 这是一个好的设计,为什么?


4
在MVC上,几个视图可以具有相同的控制器,还是一个视图必须具有一个唯一的控制器?
在围绕MVC设计项目的体系结构时遇到一些问题。(这是一个C ++ / Marmalade SDK项目,我没有使用任何特定的MVC框架,而是创建了一个。) 在几篇文章中(例如在史蒂夫·伯贝克(Steve Burbek)的原始文章中),我一直在阅读“ MVC triad”的概念,这使我感到困惑,因为我从字面上理解了这个概念。当我第一次阅读它时,看起来应用程序是围绕“ MVC triad”单元构建的(我应该为每个UI单元构建一个单元),但是我发现这相当不灵活,我认为这并不是打算使用MVC的方式。然后,进一步研究该问题,我发现了控制器和视图紧密耦合的几个示例,即一对一关系-TextEditView具有TextEditController。 但是,当我回到项目时,发现使用一个控制器(按“逻辑单元”,如AddElementController)和该特定控制器的多个视图可能会很有用。 我显然在考虑类似AddElementController之类的东西,它应该具有某种选项卡式UI。我是否应该具有一个具有AddElementTabView的AddElementController以及用于选项卡的几个AddImageView,AddSoundView等?还是每个选项卡视图都应该有一个不同的“子控制器”? 总而言之,关于MVC模式(不是X框架对此模式的特殊理解/实现),为一个控制器拥有多个视图是否正确,还是每个视图都应具有其特定的控制器? 另外,在控制器上保留一些状态信息是否正确还是应该是无状态的(意味着状态应该放在某些非域状态模型上)? 在此先感谢所有。

2
最好有单独的“创建”和“编辑”动作,还是将“创建”和“编辑”合并为一个动作?
我们正在使用带有控制器/视图表示层和模型的ASP.NET MVC 2,该模型和模型由业务逻辑层,数据访问层[存储过程和与存储过程进行通信的类/方法]组成。 在业务层及更高层中,对于大多数用途而言,编辑似乎能够代表对象的创建和对象的编辑。这与定义“保存”方法的存储库设计模式非常吻合。我们可以简单地在存储过程中检查ID是否为0,然后如果ID为0则创建一个新对象,否则我们可以只更新现有对象,因为类别ID应该匹配一个。 讨论的主要要点是,将包含创建的编辑拆分为DAL层之外的创建和编辑的单独部分是否最有意义。 一个明显的例子可以显示为路线: 创建 - HTTP:// someurl / somearea /编辑/ 0 编辑 - HTTP:// someurl / somearea /编辑/ 254 与 创建 - HTTP:// someurl / somearea /创建 编辑 - HTTP:// someurl / somearea /编辑/ 254 是否有与此相关的既定标准或最佳实践? 我知道这是一个小细节,但从逻辑上讲,这是一个重要的细节。

2
在现代编译器中如何实现泛型?
我的意思是我们如何从某些模板T add(T a, T b) ...进入生成的代码?我已经想到了几种方法来实现,我们将通用函数存储在AST中Function_Node,然后每次使用它时,都会在原始函数节点中存储其自身的副本,其中所有类型都T替换为正在使用。例如add<int>(5, 6)将存储的通用功能的副本add并替换所有类型T 的副本有int。 所以它看起来像: struct Function_Node { std::string name; // etc. Type return_type; std::vector<std::pair<Type, std::string>> arguments; std::vector<Function_Node> copies; }; 然后,您可以为这些代码生成代码,并在访问Function_Node副本列表所在的位置时copies.size() > 0调用visitFunction所有副本。 visitFunction(Function_Node& node) { if (node.copies.size() > 0) { for (auto& node : nodes.copies) { visitFunction(node); } // it's a generic function so we …

2
存储库真正应该做什么?
我听说过很多存储库模式,但是我完全不了解存储库应该真正做什么。当我说“存储库应该真正做什么”时,我主要是在担心它应该提供哪些方法。例如,存储库应该真正提供CRUD方法,还是应该提供某种其他方法? 我的意思是,存储库应包含业务逻辑,还是应仅包含与数据存储进行通信并管理要保存或加载的实体的逻辑? 我还听说存储库是聚合的持久性单位。那怎么了 我不明白这在实践中是如何工作的。我认为我们应该只有一个IRepository包含CRUD方法的接口,然后对于任何实体,实现都将仅包含用于保存和从数据存储中检索此类的逻辑。


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.