Questions tagged «design-patterns»

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

7
自执行匿名函数与原型
在Javascript中,有几种在JavaScript中创建和管理类/命名空间的突出技术。 我很好奇哪种情况需要使用一种技术而不是另一种技术。我想选一个并坚持前进。 我编写了由多个团队维护和共享的企业代码,并且我想知道编写可维护的javascript时的最佳实践是什么? 我倾向于使用自执行匿名功能,但是我很好奇社区对这些技术的投票。 原型: function obj() { } obj.prototype.test = function() { alert('Hello?'); }; var obj2 = new obj(); obj2.test(); 自闭式匿名函数: //Self-Executing Anonymous Function (function( skillet, $, undefined ) { //Private Property var isHot = true; //Public Property skillet.ingredient = "Bacon Strips"; //Public Method skillet.fry = function() { var …


4
为什么开发团队会坚持认为在Visual Studio中对多个项目使用单个解决方案会“增加相互依赖的复杂性”?
我正在帮助管理一个外部团队,他们正在开始开发某些现有产品的新版本。从历史上看,该团队一直在单个解决方案中使用单个项目的模型来处理Visual Studio中的大约30个模块,这些模块一起产生可部署的内部版本。 这会对构建可靠性和质量产生不利影响,因为它们并不总是向我们发送最新的源代码。我们试图让他们将所有引用的代码统一到一个解决方案中,但是我们遇到了一些阻力-特别是他们一直在谈论如果将所有内容都放置在模块之间,模块之间的相互依赖性(在Visual Studio中为“项目”)会增加。一个解决方案文件。单独解决方案中的代码均未在其他地方使用。 我坚持这是胡说八道,良好的开发模式将避免任何此类问题。 有问题的团队还对现有产品进行错误修复和新功能开发,至少可以说,其经验不足以解决多个解决方案的完全相同的问题。我们一直被拒绝访问其源代码管理(TFS),而我们采用的统一代码库的方法是尝试并至少减少丢失的更新数量,而不是偶尔进行回归(是的,固定的错误正越来越-产品介绍),说“向我们发送整个解决方案文件夹的ZIP文件,这样我们就可以解压缩,在Visual Studio中打开它,然后按F5 “用于测试”。在总体结构和质量方面,该代码非常差且难以支持。这种经验就是为什么我希望尽可能早地在开发周期中使工作流程正确。 有什么我想念的吗?是否有充分的理由将所有代码分开?为了我的钱,它必须是一个令人信服的理由,这将是常识,但是我更愿意承认我并不了解一切。

4
您如何处理多个用户在Webapp中编辑同一条数据?
我正在处理的一个项目正在寻找一个Web应用程序,该应用程序将管理多个用户之间的任务列表。这是一个主任务列表,其任务项由授权用户分发。每个用户都有自己的帐户来登录和查看分配给他们的任务;多个用户可能有一个共同的任务。 我试图将项目的详细信息排除在外,因为我将更多地与如何处理以下情况的整体概念作斗争,但是如果有帮助,我将使用Java,EclipseLink和GWT,并实现RequestFactory。该数据库是PostgreSQL。 因此,我尝试解决的概念性问题如下: 如果多个用户共有的单个任务以任何方式更改(例如任务完成,删除等),则具有此任务的所有用户的任务列表都将更新。有哪些设计模式可帮助实现此功能? 我查看过的某些模式是“观察员”和“调解员”-在这些模式上是否应该考虑其他模式? 假设有两个用户同时更改同一任务。 首先,我应该允许这种情况发生还是在某个人完成更改之前将其锁定? 其次,如果不加锁,我该如何调和接受谁的更改?这涉及1中的情况,因为用户1可以提交数据,并且在用户2接收更新的数据之前,他/她可能已经前进并提交了他/她的更改。 我真的在寻找您可以提供的有关如何在此Web应用程序的多个实例之间正确同步数据的任何指导点,建议或技巧。我将不胜感激!

4
如何在我的代码中避免“经理”
该问题是从Code Review Stack Exchange 迁移而来的,因为可以在Software Engineering Stack Exchange上回答。 迁移 6年前。 我目前正在为C ++ 重新设计我的实体系统,并且我有很多经理。在我的设计中,我有这些类,以便将我的库联系在一起。关于“经理”类,我听说过很多坏事,也许我没有适当地命名我的类。但是,我不知道还有什么名字。 在我的图书馆中,大多数经理都是由以下类组成的(尽管确实有所不同): 容器-管理器中对象的容器 属性-管理器中对象的属性 在我的图书馆新设计中,我有这些特定的类,以便将我的图书馆联系在一起。 ComponentManager-管理实体系统中的组件 组件容器 ComponentAttributes 场景*-对场景的引用(请参见下文) SystemManager-管理实体系统中的系统 系统容器 场景*-对场景的引用(请参见下文) EntityManager-管理实体系统中的实体 EntityPool-实体池 EntityAttributes-实体的属性(只能由ComponentContainer和System类访问) 场景*-对场景的引用(请参见下文) 场景-将所有经理联系在一起 组件管理器 系统管理员 实体管理器 我当时只是想将所有容器/池放入Scene类本身。 即 代替这个: Scene scene; // create a Scene // NOTE: // I technically could wrap this line …


3
REST端点为预见的更改进行规划的建议模式是什么
尝试为具有变更前瞻性的外部应用程序设计API并非易事,但预先考虑可以使以后的生活变得更轻松。我正在尝试建立一个方案,以支持将来的更改,同时通过保留先前的版本处理程序来保持向后兼容。 本文的主要关注点是对于给定产品/公司,所有定义的端点应遵循哪种模式。 基本方案 鉴于基本URL模板https://rest.product.com/我设计,所有的服务都位于下/api沿/auth和其他基于非休息终点如/doc。因此,我可以如下建立基本端点: https://rest.product.com/api/... https://rest.product.com/auth/login https://rest.product.com/auth/logout https://rest.product.com/doc/... 服务端点 现在是端点本身。关注度POST,GET,DELETE不是本文的主要目的,是对这些行为本身的关注。 端点可以分为名称空间和动作。每个动作还必须以支持返回类型或所需参数的基本更改的方式显示自己。 在注册用户可以发送消息的假设聊天服务中,我们可能具有以下端点: https://rest.product.com/api/messages/list/{user} https://rest.product.com/api/messages/send 现在添加版本支持,以支持将来可能会中断的API更改。之后我们既可以添加版本签名/api/或之后/messages/。给定send端点,我们可以为v1提供以下内容。 https://rest.product.com/api/v1/messages/send https://rest.product.com/api/messages/v1/send 所以我的第一个问题是,版本标识符的推荐位置是什么? 管理控制器代码 因此,现在我们已经确定需要支持以前的版本,因此需要以某种方式处理可能随着时间而弃用的每个新版本的代码。假设我们正在用Java编写端点,则可以通过包来管理它。 package com.product.messages.v1; public interface MessageController { void send(); Message[] list(); } 这样做的好处是,所有代码已通过命名空间分隔开,其中的任何重大更改都将意味着服务端点的新副本。这样做的不利之处在于,需要复制所有代码,并且希望对每个副本都应用/测试希望应用于新版本和先前版本的错误修正。 另一种方法是为每个端点创建处理程序。 package com.product.messages; public class MessageServiceImpl { public void send(String version) { getMessageSender(version).send(); } // Assume we have …

4
我应该如何向已存在的对象添加功能?
我有一个具有一定数量明确定义的功能的接口。比方说: interface BakeryInterface { public function createCookies(); public function createIceCream(); } 这对于大多数接口实现都很有效,但是在某些情况下,我需要添加一些新功能(例如,可能已添加到新方法中createBrownies())。这样做的显而易见/天真的方法是扩展接口: interface BrownieBakeryInterface extends BakeryInterface { public function createBrownies(); } 但是有一个很大的缺点,就是我不能在不修改现有API的情况下添加新功能(例如,更改类以使用新接口)。 我正在考虑使用适配器在实例化后添加功能: class BrownieAdapter { private brownieBakery; public function construct(BakeryInterface bakery) { this->brownieBakery = bakery; } public function createBrownies() { /* ... */ } } 这会让我感到类似: bakery = new …

1
Java中的模块需求与依赖注入
这些天来,我脑海中浮现出一个问题: 我们的Javascript方法是否与传统软件开发中被认为是好的做法的几乎所有东西背道而驰? 我有一系列与此陈述有关的问题/意见,但是为了遵守StackExchange的格式,将它们分成不同的问题会更好。 模块要求 如今的标准Javascript代码如下所示: const someModule = require('./someModule') module.exports = function doSomethingWithRequest() { // do stuff someModule.someFunc() // do other stuff } 好处 封装:模块独立工作,并且知道执行其功能所需的一切。 作为一种颜色,客户可以更轻松地使用该模块。 缺点 可测试性差:在不使用DI时这是标准配置,但在动态语言(例如Javscript)中,可以通过* mockery或模块来规避* rewire。 它确实违反了DIP-请勿与依赖注入混淆。-因为我只能导入具体模块。 它可能违反了OCP-例如,假设我有一个日志模块(通过fs模块)写入文件系统。如果我想扩展此日志模块以将其发送到网络,那将非常困难。 *这可能与CommonJS甚至AMD模块一起使用,因为它们大部分是在用户领域实现的。但是,我不确定使用ES6 import语法怎么可能。 依赖注入 使用依赖注入,它将更像是: module.exports = function doSomethingWithRequest(someModule) { // do stuff someModule.someFunc() // do other stuff } …

6
迭代器模式-为什么不公开内部表示很重要?
我正在阅读C#设计模式要点。我目前正在阅读有关迭代器模式的信息。 我完全了解如何实现,但不了解重要性或看不到用例。书中给出了一个示例,其中有人需要获取对象列表。他们可以通过公开公共财产(例如IList<T>或)来做到这一点Array。 这本书写道 问题是这两个类的内部表示都暴露给外部项目。 内部代表什么?事实是array或IList<T>?我真的不明白为什么这对消费者(程序员称呼这)是一件坏事…… 然后,这本书说这种模式通过公开其GetEnumerator功能而起作用,因此我们可以GetEnumerator()以此方式调用和公开“列表”。 我认为这种模式在某些情况下(与所有模式一样)都有位置,但是我看不到何时何地。

3
静态工厂vs单身工厂
在我的某些代码中,我有一个类似于以下内容的静态工厂: public class SomeFactory { // Static class private SomeFactory() {...} public static Foo createFoo() {...} public static Foo createFooerFoo() {...} } 在代码审查期间,建议将其作为一个单例并注入。因此,它应如下所示: public class SomeFactory { public SomeFactory() {} public Foo createFoo() {...} public Foo createFooerFoo() {...} } 需要强调的几件事: 两个工厂都是无状态的。 方法之间的唯一区别是它们的范围(实例与静态)。实现是相同的。 Foo是没有接口的bean。 我要静态化的参数是: 该类是无状态的,因此不需要实例化 能够调用静态方法比必须实例化工厂似乎更自然。 工厂作为单例的参数是: 注入一切都很好 尽管工厂是无状态的,但使用注入进行测试还是比较容易的(易于模拟) 测试消费者时应该嘲笑它 …

5
加载应用程序设置的最佳方法
保留Java应用程序设置的一种简单方法是使用扩展名为“ .properties”的文本文件表示,该文件包含与特定值(此值可以是数字,字符串,日期等)关联的每个设置的标识符。 。C#使用类似的方法,但文本文件必须命名为“ App.config”。在这两种情况下,都必须在源代码中初始化一个特定的类来读取设置:此类具有一种方法,该方法返回与指定的设置标识符关联的值(作为字符串)。 // Java example Properties config = new Properties(); config.load(...); String valueStr = config.getProperty("listening-port"); // ... // C# example NameValueCollection setting = ConfigurationManager.AppSettings; string valueStr = setting["listening-port"]; // ... 在这两种情况下,我们都应该解析从配置文件加载的字符串,并将转换后的值分配给相关的类型化对象(在此阶段可能发生解析错误)。解析步骤之后,我们必须检查设置值是否属于特定的有效域:例如,队列的最大大小应为正值,某些值可能是相关的(例如:min <max ), 等等。 假设应用程序应在启动时立即加载设置:换句话说,应用程序执行的第一个操作是加载设置。设置的任何无效值必须自动替换为默认值:如果一组相关设置发生这种情况,则这些设置都将设置为默认值。 执行这些操作的最简单方法是创建一个方法,该方法首先解析所有设置,然后检查加载的值,最后设置任何默认值。但是,如果使用这种方法,维护将很困难:随着开发应用程序时设置数量的增加,更新代码变得越来越困难。 为了解决此问题,我想到了如下使用“ 模板方法”模式。 public abstract class Setting { protected abstract bool TryParseValues(); protected …

7
只做一件事的类的模式
假设我有一个程序可以执行以下操作: void doStuff(initalParams) { ... } 现在,我发现“做事”是相当复杂的操作。该过程变得很大,我将其拆分为多个较小的过程,很快我意识到在进行填充时具有某种状态会很有用,因此我需要在较小的过程之间传递较少的参数。因此,我将其纳入自己的类中: class StuffDoer { private someInternalState; public Start(initalParams) { ... } // some private helper procedures here ... } 然后我这样称呼它: new StuffDoer().Start(initialParams); 或像这样: new StuffDoer(initialParams).Start(); 这就是感觉不对的地方。使用.NET或Java API时,我始终不会调用new SomeApiClass().Start(...);,这使我怀疑自己做错了。当然,我可以将StuffDoer的构造函数设为私有,并添加一个静态辅助方法: public static DoStuff(initalParams) { new StuffDoer().Start(initialParams); } 但是然后我有了一个其外部接口仅包含一个静态方法的类,这也感觉很奇怪。 因此,我的问题是:这种类型的类是否有公认的模式? 只有一个入口 是否没有“外部可识别”状态,即实例状态仅在执行该入口点时需要?


3
了解桥梁设计模式
此问题是从Stack Overflow 迁移而来的,因为可以在Software Engineering Stack Exchange上回答。 迁移 8年前。 我完全不了解“桥梁”设计模式。我浏览了各种网站,但没有帮助。 有人可以帮助我理解这一点吗?

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.