Questions tagged «design-patterns»

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

8
做设计模式扼杀创造力
许多年前,我曾与经济学教授讨论设计模式,如何为程序员建立通用语言以及如何以良好的方式解决众所周知的问题等。 然后,他对我说,这与他的经济学学生所用的方法完全相反。他通常会提出一个问题,并要求他们首先找到解决方案,因此他们可以先考虑一下,然后尝试找到首先解决问题的方法,然后才提出“经典”解决方案。 所以我在想,“设计模式”方法是否真的会使程序员变得更聪明或更笨拙,因为他们很多时候只是获得“针对此问题的正确解决方案”,而不是利用创造力和想象力来解决某个问题。创新的方式。 你怎么看?

6
功能图与switch语句
我正在处理一个处理请求的项目,该请求有两个组件:命令和参数。每个命令的处理程序非常简单(<10行,经常<5)。至少有20条命令,可能会超过50条。 我提出了一些解决方案: 一个大的开关/ if-else命令 命令到功能的映射 命令到静态类/单的映射 每个命令都进行一点错误检查,唯一可以抽象的位是检查为每个命令定义的参数数量。 什么是解决此问题的最佳解决方案,为什么?我也愿意接受我可能错过的任何设计模式。 我为每个提出了以下优点/缺点列表: 开关 优点 将所有命令保持在一个功能中;由于它们很简单,因此使其成为可视化查找表 不需要使用大量只会在一个地方使用的小功能/类来弄乱源代码 缺点 很长 难以以编程方式添加命令(需要使用默认大小写进行链接) 映射命令->功能 优点 一口大小的小块 可以以编程方式添加/删除命令 缺点 如果在线完成,则外观与开关相同 如果没有在线完成,很多功能只能在一个地方使用 映射命令->静态类/单例 优点 可以使用多态来处理简单的错误检查(仅3行,但仍然) 与map类似的好处->功能解决方案 缺点 很多非常小的班级将使项目混乱 实施并非都在同一个地方,因此扫描实施并非易事 额外说明: 我正在用Go编写此代码,但是我认为解决方案不是特定于语言的。我正在寻找一个更通用的解决方案,因为我可能需要用其他语言做一些非常相似的事情。 命令是字符串,但是如果方便的话,我可以轻松地将其映射为数字。函数签名类似于: Reply Command(List<String> params) Go具有顶级功能,而我正在考虑的其他平台也具有顶级功能,因此第二个和第三个选项之间的区别。

1
对象转换的设计模式(java)
除了偶尔的工厂和MVC之外,我不经常使用设计模式,我想更多地使用它们。 我手头有一个具体案例,希望您对在这种情况下使用设计模式有意见。 在我的应用程序中,我不得不经常在不同情况下转换对象。我可能必须将Hibernate POJO转换为DTO,因为我使用GWT,并且Hibernate POJO不能序列化,也不能通过线路发送。 在另一种情况下,我可能需要将Java对象转换为SolrInputDocument的对象,以便由Solr进行索引。 我想知道是否应该为此使用设计模式。看来“对象转换”是一种通用任务,可以通过一种模式以灵活/抽象的方式进行处理,但是我真的不知道如何实现。 如果没有模式,我只会为每种转换类型创建一个单独的类,例如CourseToSolrInputDocument(Course是我的应用程序中的Hibernate实体)。或CourseToCourseDTO。这些转换类中的每一个都可能具有一个称为的静态方法convert(),该方法将源对象作为输入并返回输出对象。 但这不是一个真正的模式,对吗?因此,我从泛型入手,并创建了实现Converter接口的此类。但是以某种方式感到傻傻的创建了一个通用的接口,除了能够祝贺自己使用通用外,我没有真正的优势。 public class CourseToSolrInputDocument implements Converter<Course, SolrInputDocument> { @Override public void convert(Course source, SolrInputDocument destination) { //To change body of implemented methods use File | Settings | File Templates. } } 因此,这里的真正问题是:是否存在适用于通用对象转换的模式?您的方法是什么?与仅使用每个转换类的类型方法相比,优点是什么?

5
如何避免巨型胶水方法?
在我目前的工作中,我曾几次被要求清理旧代码。通常,代码是迷宫式的,其背后的数据甚至更复杂。我发现自己将事情整理成漂亮,整洁的模块化方法。每种方法都做一件事并且做得很好。那时候事情开始往南走... 最终,我总是得到一个干净的API,并且没有真正的方法将它们捆绑在一起。解决方法是编写一个大的丑陋的“粘合”方法(通常充满条件语句),该方法最终调用我所有的“清洁”方法。 胶水方法通常最终是我试图清除的代码/数据缠结的简洁版本。它通常更具可读性,但仍然很烦人。 如何避免这种方法?这是数据纠结的征兆还是我做错事情的反映?

5
如何说服我的老板(和其他开发人员)使用/考虑不引人注目的JavaScript
我在develepors团队中很新。 我需要一些强有力的论据和/或“陷阱”示例,因此我的老板将最终了解Unobtrusive JavaScript的优势,以便他和团队中的其他成员停止这样做: <input type="button" class="bow-chicka-wow-wow" onclick="send_some_ajax(); return false;" value="click me..." /> 和 <script type="text/javascript"> function send_some_ajax() { // bunch of code ... BUT using jQuery !!! } </script> 我建议使用一种非常常见的模式: <button id="ajaxer" type="button">click me...</button> 和 <script type="text/javascript"> // since #ajaxer is also delivered via ajax, I bind events to document …

3
如何为复杂的对象模型实现存储库模式?
此问题是从Stack Overflow 迁移而来的,因为可以在Software Engineering Stack Exchange上回答。 迁移 7年前。 我们的数据模型具有将近200个类别,可以分为大约十二个功能区域。使用域本来很好,但是分隔不是那么干净,我们不能更改它。 我们正在重新设计DAL以使用实体框架,而我所看到的大多数建议都建议使用存储库模式。但是,这些示例都没有真正处理复杂的对象模型。我发现一些实现建议使用每个实体存储库。对于大型,复杂的模型,这似乎是荒谬的且不可维护的。 真的有必要为每个操作创建一个UnitOfWork,并为每个实体创建一个Repository吗?我可能会参加数千堂课。我知道这是不合理的,但是我发现在复杂模型和实际业务应用程序上实现存储库,工作单元和实体框架的指导很少。

1
学习异步编程
关闭。这个问题是题外话。它当前不接受答案。 想改善这个问题吗? 更新问题,使它成为软件工程堆栈交换的主题。 4年前关闭。 异步非阻塞事件驱动的编程似乎风行一时。我对这一切意味着什么有基本的概念理解。但是,我不确定的是我的代码何时何地可以从异步中受益,或者如何使阻塞式IO成为非阻塞式。我敢肯定,我可以简单地使用一个库来做到这一点,但是我对更深入的概念以及自己实现它的各种方式更感兴趣。 是否有任何全面/权威书籍或其他资源在这个问题上(如GoF的设计模式,或K&R为C,TLDP对于像bash)的? (注意:我不确定这在功能上是否与我学习事件驱动编程有关的问题相同)

4
使用方法链接构建对象的成语叫什么名字?
我经常使用一种模式,在该模式下,我使用方法链来设置一个对象,类似于Builder或Prototype模式,但没有在每个方法调用中创建新对象,而是修改了原始对象。 例: new Menu().withItem("Eggs").withItem("Hash Browns").withStyle("Diner"); 只是想知道这种模式是否有名称,以及是否将其视为反模式,因为尽管它可以更流畅地阅读,但它可能导致较长的方法链。

4
有没有人有使用举重模式的特定示例?[关闭]
已关闭。这个问题需要更加集中。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅通过编辑此帖子来关注一个问题。 2年前关闭。 我一直在研究设计模式,并遇到了飞行重量模式。我一直在尝试寻找在我的应用程序中使用该模式的机会,但是我在查看如何使用它方面遇到了麻烦。另外,当我阅读其他人的代码时,有哪些迹象表明正在使用飞行重量模式? 根据定义,它说: 使用共享可以有效地支持大量细粒度的对象。 如果我没看错,Dictionary和Hashtables可能是飞行重量的实例,这是正确的吗? 提前致谢。

3
如何存储有生效日期的价格?
我有一个产品清单。每个都由N个提供者提供。 每个提供商都为我们提供特定日期的价格。该价格一直有效,直到该提供商决定设置新价格。在这种情况下,提供商将使用新日期给出新价格。 MySQL表标头当前看起来像: provider_id, product_id, price, date_price_effective 每隔一天,我们会汇总当天有效的产品/价格列表。对于每种产品,该列表包含具有该特定产品的提供者的排序列表。这样,我们可以从碰巧提供最佳价格的任何人那里订购某些产品。 为了获得有效的价格,我有一条SQL语句返回所有具有的行date_price_effective >= NOW()。该结果集由ruby脚本处理,该脚本进行必要的排序和过滤以获取如下所示的文件: product_id_1,provider_1,provider_3,provider8,provider_10... product_id_2,provider_3,provider_2,provider1,provider_10... 对于我们的目的来说,这很好用,但是我仍然觉得SQL表可能不是存储此类信息的最佳方法。我感到这种问题以前已经以其他更具创造性的方式解决了。 除了在SQL中,还有其他更好的方法来存储此信息吗?或者,如果使用SQL,是否有比我正在使用的方法更好的方法?


3
大量参数的构造函数与构造器模式
众所周知,如果您的类的构造函数带有许多参数,例如超过4个,则很可能是代码气味。您需要重新考虑该类是否满足SRP要求。 但是,如果我们构建并反对依赖10个或更多参数的对象,并最终通过Builder模式设置所有这些参数,该怎么办?想象一下,您Person用其个人信息,工作信息,朋友信息,兴趣信息,教育信息等构建了一个类型对象。这已经很好了,但是您可以通过多个4来设置相同的参数,对吗?为什么这两种情况不一样?

5
为什么将类型与生成器结合在一起?
我最近在Code Review上删除了我的一个Java答案,它的开始是这样的: private Person(PersonBuilder builder) { 停止。红色标志。一个PersonBuilder将建立一个Person;它知道一个人。Person类应该对PersonBuilder一无所知-这只是一个不可变的类型。您已经在此处创建了圆形耦合,其中A取决于B,而B取决于A。 该人员应仅获取其参数;愿意创建一个人而不创建它的客户应该能够做到这一点。 我被选票打了耳光,并告诉我(引用)红旗,为什么?这里的实现与Joshua Bloch在其“ Effective Java”书(项目2)中演示的形状相同。 因此,看来在Java 中实现构建器模式的一种正确方法是使构建器成为嵌套类型(尽管这不是这个问题),然后制造产品(正在构建的对象的类) )对构建器的依赖,如下所示: private StreetMap(Builder builder) { // Required parameters origin = builder.origin; destination = builder.destination; // Optional parameters waterColor = builder.waterColor; landColor = builder.landColor; highTrafficColor = builder.highTrafficColor; mediumTrafficColor = builder.mediumTrafficColor; lowTrafficColor = builder.lowTrafficColor; } https://zh.wikipedia.org/wiki/Builder_pattern#Java_example 对于相同的Builder模式,相同的Wikipedia页面对于C#具有非常不同的实现(并且更加灵活): //Represents …

5
在几乎每个人都需要访问公共数据结构的情况下,依赖项注入有什么好处?
在OOP中,为什么全局变量是邪恶的有很多原因。 如果需要共享的对象的数量或大小太大而无法在函数参数中有效传递,通常每个人都建议使用依赖注入而不是全局对象。 但是,在几乎每个人都需要了解某种数据结构的情况下,为什么依赖注入比全局对象更好? 示例(一个简化的示例,以大体上说明这一点,而无需在特定应用程序中深入研究) 许多虚拟车辆具有大量的属性和状态,包括类型,名称,颜色,速度,位置等。许多用户可以对其进行远程控制,并且发生大量事件(用户都可以已启动和自动)可以更改其许多状态或属性。 天真的解决方案是仅将它们制成一个全局容器,例如 vector<Vehicle> vehicles; 可以从任何地方访问。 更加面向OOP的解决方案是让容器成为处理主事件循环的类的成员,并在其构造函数中实例化。每个需要它并且是主线程成员的类都将通过其构造函数中的指针被授予对容器的访问权限。例如,如果外部消息是通过网络连接传入的,则负责解析的类(每个连接一个)将接管,解析器将可以通过指针或引用访问容器。现在,如果解析后的消息导致容器元素发生更改,或者需要容器中的某些数据来执行操作,则无需通过信号和插槽来扔掉成千上万个变量(或更糟的是,将它们存储在解析器中,稍后由调用解析器的人检索)。当然,所有通过依赖注入接收对容器的访问的类都是同一线程的一部分。不同的线程不会直接访问它,但是会执行其工作,然后将信号发送到主线程,并且主线程中的插槽将更新容器。 但是,如果大多数类都可以访问该容器,那么到底它与全局容器有什么不同呢?如果这么多的类需要容器中的数据,那么“依赖注入方式”是否只是伪装的全局变量? 一个答案将是线程安全性:即使我注意不要滥用全局容器,也许将来另一个开发人员在紧迫的最后期限的压力下,仍会在另一个线程中使用全局容器,而不会照顾所有人碰撞情况。但是,即使在依赖注入的情况下,也可能会向在另一个线程中运行的某个人提供指针,从而导致相同的问题。


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.