Questions tagged «design-patterns»

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

3
谁应该控制MVVM应用程序中的导航?
例1:我的MVVM应用程序中显示了一个视图(出于讨论目的,请使用Silverlight),然后单击一个按钮,该按钮会将我带到新页面。 示例2:同一视图具有另一个按钮,单击该按钮后应在子窗口(对话框)中打开详细信息视图。 我们知道,将有ViewModel公开的Command对象绑定到按钮,这些对象具有响应用户单击的方法。但是,那又如何呢?我们如何完成该动作?即使我们使用所谓的NavigationService,我们在说什么呢? 更具体地说,在传统的“视图优先”模型(如基于URL的导航方案,例如Web或SL内置导航框架)中,Command对象必须知道接下来要显示的视图。当涉及由模式促进的关注点分离时,这似乎越界了。 另一方面,如果未将按钮连接到Command对象,并且其行为类似于超链接,则可以在标记中定义导航规则。但是我们是否希望Views控制应用程序流,并且导航不只是另一种业务逻辑吗?(在某些情况下我可以说是,在其他情况下我可以说不。) 对我来说,MVVM模式的乌托邦式实现(我听说其他人对此表示赞同)将以一种可以使应用程序无头运行(即无视图)的方式连接ViewModel。这为基于代码的测试提供了最大的表面积,并使Views成为应用程序的真实外观。而且我的ViewModel不在乎它是否显示在主窗口,浮动面板或子窗口中,应该吗? 根据这种方法,在运行时由其他机制来“绑定”应该为每个ViewModel显示的视图。但是,如果我们想与多个ViewModel共享一个View,反之亦然呢? 因此,鉴于需要管理View-ViewModel关系,以便我们知道在视图之间导航时需要显示的内容(包括显示子窗口/对话框),我们如何真正在MVVM模式中完成此操作?

8
使用枚举列表是否是一个好习惯?
我目前正在一个有用户的系统上工作,每个用户都有一个或多个角色。在User上使用Enum值列表是一种好习惯吗?我想不出更好的办法,但这感觉还不错。 enum Role{ Admin = 1, User = 2, } class User{ ... List<Role> Roles {get;set;} }

5
为什么现在n层开发中的代码库现在有相等数量(甚至更多)的JavaScript代码?
我已经从事Web编程很长时间了,在某个地方,我无法知道为什么我们现在正在做我们所做的事情(或者我们是如何以这种方式来做事情的)? 我从基本的ASP Web开发开始,很早就在页面上混合了显示和业务逻辑。客户端开发之间千差万别(VBScript,不同的JavaScript风格),并且我们对服务器端验证有很多警告(因此我远离客户端逻辑)。 然后我搬到了ColdFusion了一段时间。ColdFusion可能是第一个使用其标签将显示和业务逻辑分开的Web开发框架。对我来说似乎很清楚,但非常冗长,并且ColdFusion的市场需求不高,所以我继续前进。 然后,我跳上ASP.NET的旅行车,开始使用他们的MVC方法。我还意识到Java似乎是企业系统的象牙塔语言,并尝试了MVC方法。后来,ASP.NET开发了这种MVVM设计模式,而Java(准确地说是J2EE或JEE)也很挣扎,并提出了其MVC2方法。 但是今天,我发现,后端编程不再是令人兴奋和进步的地方。而且,基于服务器端的MVC做法似乎已经过时了(人们真的不再使用JSTL吗?)。今天,在我从事的大多数项目中,我发现JavaScript框架和客户端开发是所有令人激动和创新的进步的来源。 为什么要进行从服务器到客户端的开发?我对我的一个JEE项目进行了简单的行计数,并且JavaScript中的代码行比Java多(第三方库除外)。我发现使用Java或C#等编程语言进行的大多数后端开发只是为了生成类似REST的界面,并且解决了显示,可视化,数据输入/输出,用户交互等所有艰苦的工作。通过诸如Angular,Backbone,Ember,Knockout等客户端框架... 在jQuery之前的时代,我看到了很多图,其中n层开发中的MVC中的M,V和C之间存在清晰的概念性界线。jQuery后,这些线在哪里绘制?看起来MVC和MVVM都可以在客户端的JavaScript代码中找到。 我想知道的是,为什么我们要进行这样的转换(从服务器端编程的重点到客户端的方方面面,从偏爱编译语言到脚本语言,从命令式到功能性编程,所有这些似乎都是同时发生的) ),此过渡/转移解决了哪些问题?

9
我们应该避免在不断变化的项目中使用设计模式吗?
我的一个朋友正在一家小公司工作,每个开发人员都讨厌这个项目:他被迫尽快发布,他是唯一一个关心技术债务,客户没有技术背景的人。 他给我讲了一个故事,使我想到了这样的项目中设计模式的适当性。这是故事。 我们不得不在网站的不同位置展示产品。例如,内容管理者可以通过API查看产品,还可以查看最终用户或合作伙伴。 有时,产品中缺少信息:例如,刚创建产品时,其中一堆没有任何价格,但尚未指定价格。有些没有描述(描述是具有修改历史,本地化内容等的复杂对象)。一些缺乏货运信息。 受到最近关于设计模式的阅读的启发,我认为这是使用神奇的Null Object模式的绝佳机会。所以我做到了,一切都变得顺畅而干净。只需致电product.Price.ToString("c")显示价格或product.Description.Current显示说明即可;不需要有条件的东西。直到一天,涉众要求通过使用nullJSON 来以不同的方式在API中显示它。对于内容管理者,也显示“未指定价格[更改]”,这也有所不同。而且我不得不谋杀我心爱的Null Object模式,因为不再需要它了。 同样,我不得不删除一些抽象工厂和一些建筑商,最终我通过直接和丑陋的调用替换了我美丽的Facade模式,因为底层接口在三个月中每天两次更改,甚至Singleton也离开了我当需求告知相关对象必须根据上下文而不同时。 超过三周的工作包括添加设计模式,然后在一个月后将其撕裂,我的代码最终变得面目全非,甚至包括我自己在内的任何人都无法维护。最好首先不要使用这些模式,这会更好吗? 确实,我必须在那些要求不断变化的项目类型上工作,而这些项目实际上是由那些并不真正考虑产品的凝聚力或一致性的人所决定的。在这种情况下,无论您有多敏捷,都将为问题提供一个优雅的解决方案,当最终实现该问题时,您会发现需求发生了巨大变化,以致于您的优雅解决方案不适合不再。 在这种情况下,解决方案是什么? 是否不使用任何设计模式,停止思考并直接编写代码? 进行一次团队直接编写代码,而另一个团队在打字之前三思而后行的经历会很有趣,这冒着几天后不得不扔掉原始设计的风险:谁知道,也许两个团队都会拥有同样的技术债务。如果没有这样的数据,我只断言,它不觉得不对劲,恕不另行思维上有20人月的项目工作时输入代码。 保留不再有意义的设计模式,并尝试为新创建的情况添加更多模式? 这似乎也不正确。模式用于简化对代码的理解;放置过多的模式,代码将变得一团糟。 开始考虑包含新要求的新设计,然后慢慢将旧设计重构为新设计? 作为一名理论家和偏爱敏捷的人,我完全投入其中。在实践中,当您知道必须每周回到白板并重做以前的设计的大部分内容时,并且客户只是没有足够的资金来支付您的费用,也没有足够的时间等待,这可能行不通。 那么,有什么建议吗?

3
最小惊讶的原理是什么?
在编程中,什么是最小惊讶原理?这个概念与设计好的API有什么关系?这是否仅适用于面向对象的编程,还是也渗透到其他编程技术中?这是否与“在您的方法中做一件事情并做好事”的原则有关?

11
设计良好/高质量的开源软件
我正在参加软件设计课程,我应该从软件设计的角度选择一个开源软件进行分析。 它必须是一个大项目:不少于100,000行代码。 我真的很想选择一种设计和架构都很好的软件,以便对好的软件设计有深刻的见解。 所谓好的设计,是指诸如有意义的类和体系结构,(设计)模式的良好使用,抽象的良好使用,组件的良好组织,组件之间的高内聚和低耦合等。 您有什么软件可以建议我吗? 请注意,软件只需要具有良好的设计,而无需将设计记录在案!:) 它不一定是最终用户的应用程序...也可以是库,工具等...

2
选择正确的设计模式
我一直都认识到利用设计模式的重要性。我对其他开发人员如何选择最合适的开发人员感到好奇。您是否使用一系列特征(例如流程图)来帮助您做出决定? 例如: 如果对象是相关的,但是我们不想指定具体的类,请考虑Abstract 将实例化留给派生类时,请考虑使用Factory 需要顺序访问聚合对象的元素,请尝试使用Iterator 或类似的东西?


1
“ StringBuilder”是Builder设计模式的应用程序吗?
是“构建器”模式仅限于解决“ telescoping构造函数”反模式,还是可以说也解决了复杂的不可变对象创建这一更普遍的问题? 该StringBuilder班在其名称中的“建设者”,但它没有任何可伸缩的构造函数,它只是帮助我们收集了所有我们需要传递给一个不可变对象的构造函数的数据。 在我看来,答案似乎是非常明确的“是”,但是在该主题上似乎存在一些分歧,因此我希望有人可以对此进行澄清。 我在回答这个问题:程序员SE:在构造函数中合法的“实际工作”?OP想要创建一个包含复杂树的(可能是不可变的)对象,然后弹出“ builder”模式的想法,在研究它时,我发现了这个问答,似乎是在说“ StringBuilder”风格的对象创建是不是 “建设者”模式的应用,这是我不明白原因:#1 - StringBuilder的和Builder模式。(据我所知,回答该问题的人未能提出令人信服的观点。)

9
为什么在实现Builder模式时我们需要一个Builder类?
我已经看到了Builder模式的许多实现(主要是Java)。它们都有一个实体类(假设是一个Person类)和一个构建器类PersonBuilder。构建器“堆叠”各种字段,并返回new Person带有传递的参数的。为什么我们显式需要一个构建器类,而不是将所有构建器方法放在Person类本身中? 例如: class Person { private String name; private Integer age; public Person() { } Person withName(String name) { this.name = name; return this; } Person withAge(int age) { this.age = age; return this; } } 我可以简单地说 Person john = new Person().withName("John"); 为什么需要PersonBuilder上课? 我看到的唯一好处是,我们可以将Person字段声明为final,从而确保了不变性。

10
您通常将对象或其成员变量发送到函数中吗?
这两种情况之间普遍接受的做法是: function insertIntoDatabase(Account account, Otherthing thing) { database.insertMethod(account.getId(), thing.getId(), thing.getSomeValue()); } 要么 function insertIntoDatabase(long accountId, long thingId, double someValue) { database.insertMethod(accountId, thingId, someValue); } 换句话说,通常是将整个对象传递给您,还是只传递所需的字段,这更好吗?

7
在循环中设置标记以供以后使用是否有代码味道?
我有一段代码在其中迭代地图,直到某个条件为真,然后再使用该条件做更多的事情。 例: Map<BigInteger, List<String>> map = handler.getMap(); if(map != null && !map.isEmpty()) { for (Map.Entry<BigInteger, List<String>> entry : map.entrySet()) { fillUpList(); if(list.size() > limit) { limitFlag = true; break; } } } else { logger.info("\n>>>>> \n\t 6.1 NO entries to iterate over (for given FC and target) \n"); } if(!limitFlag) …

9
是否只有在动态类型化语言(如Python)中才有可能的设计模式?
我读过一个相关的问题,在动态语言(如Python)中是否有不需要的设计模式?并记得Wikiquote.org上的这句话 动态类型的妙处在于它使您可以表达任何可计算的内容。而类型系统则不是-类型系统通常是可决定的,它们将您限制为一个子集。支持静态类型系统的人说:“很好,足够好;您要编写的所有有趣程序都将作为类型使用。” 但这很荒谬—一旦有了类型系统,您甚至都不知道那里有什么有趣的程序。 ---软件工程电台第140集:Gilad Bracha的Newspeak和可插拔类型 我想知道,是否有有用的设计模式或策略使用引号的表述“不能作为类型工作”?

3
ActiveRecord模式的缺点是什么?
我很好奇将ActiveRecord模式用于数据访问/业务对象的缺点是什么。我能想到的唯一一个就是违反了单一责任原则,但是AR模式很常见,以至于仅凭这个原因似乎不足以证明不使用它(当然,视图可能会偏斜,因为我使用的代码通常都没有遵循任何 SOLID原则)。 我个人不是 ActiveRecord的粉丝(除了编写Ruby on Rails应用程序,AR感觉很“自然”),因为我觉得类做得太多,并且数据访问不应该取决于类本身处理。我更喜欢使用返回业务对象的存储库。我使用的大多数代码都倾向于使用ActiveRecord的变体,形式为(我不知道为什么该方法是布尔值): public class Foo { // properties... public Foo(int fooID) { this.fooID = fooID; } public bool Load() { // DB stuff here... // map DataReader to properties... bool returnCode = false; if (dr.HasRows) returnCode = true; return returnCode; } } 或有时更“传统”的方式public static Foo FindFooByID(int …

10
抽象类上的接口
我和我的同事对基类和接口之间的关系有不同的看法。我相信一个类不应实现接口,除非在需要实现接口时可以使用该类。换句话说,我喜欢看这样的代码: interface IFooWorker { void Work(); } abstract class BaseWorker { ... base class behaviors ... public abstract void Work() { } protected string CleanData(string data) { ... } } class DbWorker : BaseWorker, IFooWorker { public void Work() { Repository.AddCleanData(base.CleanData(UI.GetDirtyData())); } } DbWorker是获得IFooWorker接口的对象,因为它是该接口的可实例化实现。它完全履行了合同。我的同事更喜欢几乎相同的东西: interface IFooWorker { void Work(); } …

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.