Questions tagged «design-patterns»

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

13
那么Singletons不好,那又如何呢?
最近,关于使用(和过度使用)Singleton的问题进行了很多讨论。我也是我职业生涯早期的那些人之一。我可以看到问题出在哪里,但是,在许多情况下,我看不到一个很好的选择-而且,很少有反辛格尔顿的讨论真正提供过这样的讨论。 这是我参与的一个近期重大项目的真实示例: 该应用程序是一个胖客户端,具有许多单独的屏幕和组件,它们使用来自服务器状态的大量数据,这些数据并不经常更新。该数据基本上被缓存在Singleton“管理器”对象中-可怕的“全局状态”。想法是在应用程序中拥有一个位置来保存和同步数据,然后打开的任何新屏幕都可以从那里查询它们的大部分需求,而无需从服务器重复请求各种支持数据。不断地向服务器请求会占用太多带宽-我说的是每周要多付数千美元的互联网账单,所以这是不能接受的。 除了基本具有这种全局数据管理器缓存对象之外,还有其他合适的方法吗?当然,此对象不一定要正式是“ Singleton”,但从概念上讲,成为一个对象确实有意义。这里有什么不错的清洁选择?

12
“业务逻辑应该在服务中而不在模型中”的准确性如何?
情况 今天晚上早些时候,我回答了关于StackOverflow的问题。 问题: 现有对象的编辑应该在存储层还是在服务中进行? 例如,如果我有一个负债的用户。我想改变他的债务。我应该通过获取对象,对其进行编辑并保存来在UserRepository或服务(例如BuyingService)中进行操作吗? 我的答案: 您应该将将一个对象变异为相同的对象,并使用存储库来检索该对象。 情况示例: class User { private int debt; // debt in cents private string name; // getters public void makePayment(int cents){ debt -= cents; } } class UserRepository { public User GetUserByName(string name){ // Get appropriate user from database } } 我收到的评论: 业务逻辑实际上应该在服务中。不在模型中。 互联网怎么说? …

17
为什么全球国家如此邪恶?
在我们开始之前,让我说我非常了解抽象和依赖注入的概念。我不需要在这里睁开眼睛。 好吧,我们大多数人在没有真正理解的情况下说了太多次了,“不要使用全局变量”,或者“ Singletons之所以邪恶是因为它们是全局的”。但真正是如此不好的不祥的全局状态? 假设我需要为应用程序进行全局配置,例如系统文件夹路径或应用程序范围的数据库凭据。 在那种情况下,除了在某种全局空间中提供这些设置之外,我看不到任何好的解决方案,这对于整个应用程序都是通用的。 我知道这是不好的滥用,但是全球空间真的THAT邪?如果是的话,那里有什么好的替代方案?


18
一个人如何管理上千条IF ... THEN ... ELSE规则?
我正在考虑构建一个应用程序,该应用程序的核心是数千个if ... then ... else语句。该应用程序的目的是能够预测奶牛在任何景观中如何移动。他们受到太阳,风,食物来源,突发事件等的影响。 如何管理这样的应用程序?我想象在经过数百个IF语句之后,程序将如何响应并调试导致某种反应的结果将意味着每次必须遍历整个IF语句树,这将是无法预测的好。 我已经阅读了一些有关规则引擎的内容,但是我看不到它们如何克服这种复杂性。

16
我的老板要求我停止编写小的函数,并在同一循环中完成所有操作
我已经读过罗伯特·C·马丁(Robert C. Martin)的一本名为《清洁代码》的书。在本书中,我看到了许多清理代码的方法,例如编写小的函数,仔细选择名称等。这似乎是迄今为止我所读过的最有趣的有关干净代码的书。但是,今天我的老板不喜欢我看完本书后写代码的方式。 他的论据是 编写小函数很痛苦,因为它迫使您进入每个小函数以查看代码在做什么。 即使主循环超过300行,也可以将所有内容放入主大循环中,以使其读取速度更快。 仅在必须复制代码时编写小型函数。 不要使用注释名称编写函数,而是将复杂的代码行(3-4行)放在注释上方;同样,您可以直接修改失败的代码 这与我读过的所有内容背道而驰。您通常如何编写代码?一个主要的大循环,没有小的功能? 我使用的语言主要是Javascript。由于我删除了所有小的明确命名的函数并将所有内容放入一个大循环中,因此我现在真的很难阅读。但是,我的老板喜欢这种方式。 一个例子是: // The way I would write it if (isApplicationInProduction(headers)) { phoneNumber = headers.resourceId; } else { phoneNumber = DEV_PHONE_NUMBER; } function isApplicationInProduction(headers) { return _.has(headers, 'resourceId'); } // The way he would write it // Take the right resourceId …

10
传递参数的(反)模式是否有名称,将仅在调用链的多个级别使用?
我试图在某些旧代码中找到使用全局变量的替代方法。但是这个问题与技术选择无关,我主要关注的是术语。 显而易见的解决方案是将参数传递给函数,而不是使用全局变量。在此传统代码库中,这意味着我必须更改长调用链中最终将使用该值的点与首先接收该参数的函数之间的所有函数。 higherlevel(newParam)->level1(newParam)->level2(newParam)->level3(newParam) newParam在我的示例中,where 以前是全局变量,但可能是以前的硬编码值。关键是,现在newParam的值是从获得的,higherlevel()并且必须一直“移动”到level3()。 我在想,如果有一个姓名(或名称)的这种情况下,你需要一个参数添加到许多功能只是“传”未经修改的值/模式。 希望使用正确的术语将使我能够找到有关重新设计解决方案的更多资源,并向同事描述这种情况。

10
为什么我们在设计模式中需要这么多的类?
我是大四学生中的初级开发人员,并且在理解他们的思维和推理方面付出了很多努力。 我正在阅读域驱动设计(DDD),无法理解为什么我们需要创建这么多的类。如果采用这种设计软件的方法,我们最终将得到20-30个类,最多可以替换为两个文件和3-4个函数。是的,这可能很麻烦,但是它更具可维护性和可读性。 每当我想查看某种EntityTransformationServiceImpl功能时,都需要遵循许多类,接口,它们的函数调用,构造函数,它们的创建等等。 简单的数学: 60行伪代码与10类X 10(假设我们有完全不同的逻辑)= 600行杂乱代码与100类+更多包装和管理它们;不要忘记添加依赖项注入。 读取600行凌乱代码=一天 100节课=一周,仍然忘记哪个课什么时候 每个人都说它易于维护,但是为什么呢?每次添加新功能时,都会添加五个带有工厂,实体,服务和值的类。我觉得这种代码的运行速度比凌乱的代码要慢得多。 假设,如果您在一个月内编写了50K LOC混乱代码,则DDD内容需要进行大量审查和更改(我都不介意在两种情况下进行测试)。一个简单的添加可能需要数周,甚至更多。 一年之内,您编写了很多混乱的代码,甚至可以多次重写它,但是使用DDD样式,您仍然没有足够的功能来与混乱的代码竞争。 请解释。为什么我们需要这种DDD样式和许多模式? UPD 1:我收到了很多不错的答案,请大家在某处添加评论或使用阅读列表的链接编辑您的答案(不确定从哪开始,DDD,设计模式,UML,代码完成,重构,实用性等。) ..那么多好书),当然还有顺序,这样我就可以像你们中的一些人一样开始理解并成为高级。

14
“从没有做过代码就无法使SQL Server为您做的更好”-这是设计不良的秘诀吗?
我在很多地方都听到过这个想法。或多或少地认识到,一旦尝试仅使用SQL解决问题就超过了一定程度的复杂性,那么您确实应该在代码中进行处理。 这个想法背后的逻辑是,在大多数情况下,数据库引擎在寻找完成任务的最有效方式方面将比在代码中做得更好。尤其是涉及将结果取决于对数据执行的操作之类的事情时。可以说,对于现代引擎而言,有效地JIT'ing +缓存查询的编译版本在表面上是有意义的。 问题是,以这种方式利用数据库引擎是否本质上是不良的设计实践(以及为什么)。当所有逻辑都存在于数据库中并且您只是通过ORM命中它时,这些界限会进一步模糊。

10
真正的MVC是什么?
作为一名认真的程序员,您如何回答MVC是什么? 在我看来,MVC是一个模糊的主题,因此,如果您的受众是学习者,那么您可以自由地以不太可能引起争议的通用术语来描述它。 但是,如果您是在与知识渊博的听众(尤其是采访员)交谈时,我很难考虑采取这样的方向,而不会冒“不正确!!”的反应。我们都有不同的实际经验,而且我还没有真正两次遇到相同的MVC实现模式。 具体来说,似乎在严格性,组件定义,零件分离(适合什么地方)等方面存在分歧。 因此,我该如何以正确,简洁和无争议的方式解释MVC?

9
为什么要使用工厂类而不是直接对象构造?
我已经在GitHub和CodePlex上看到了几个С#和Java类库项目的历史,并且看到了切换到工厂类而不是直接对象实例化的趋势。 为什么要广泛使用工厂类?我有一个很好的库,通过老式的方式创建对象-通过调用类的公共构造函数。在最后的提交中,作者迅速将所有数千个类的公共构造函数更改为内部构造,并且还创建了一个具有数千个CreateXXX静态方法的巨大工厂类,这些静态方法通过调用类的内部构造函数来返回新对象。外部项目API损坏了,做得很好。 为什么这样的更改有用?用这种方式重构的目的是什么?用静态工厂方法调用替换对公共类构造函数的调用有什么好处? 什么时候应该使用公共构造函数,什么时候应该使用工厂?

4
什么是反腐败层?如何使用?
我正在尝试弄清“反腐败”层的真正含义。我知道这是一种过渡/解决旧代码或错误API的方法。我不明白的是它是如何工作的,是什么使它与不良层完全分离。 我已经进行了一些搜索,但是找不到任何简单的示例或解释,因此我正在寻找可以理解并可以通过简单示例进行解释的人员。可以满足我的问题的答案应该很简单(不一定要简短),并提供易于理解的实现和使用示例。 有关我的用例,请参见此问题。

14
四人帮是否彻底探索了“模式空间”?
自从我至少在10年前首次了解四人一组(GoF)设计模式以来,我一直以为这23种模式应该只是更大的东西的小样本,我称之为模式空间。假设的模式空间包括针对常见的面向对象软件设计问题的所有推荐解决方案(已知或未知)。 因此,我期望已知和记录在案的设计模式数量会大大增加。 它没有发生。GoF书问世20多年来,Wikipedia文章中仅列出了12种其他模式,其中大多数都不如原始模式流行。(我未在此处包括并发模式,因为它们涉及特定主题。) 是什么原因 GoF模式集实际上是否比我想象的更全面? 寻找新模式的兴趣下降了吗,也许是因为发现它们在软件设计中并不是那么有用? 还有吗

13
设计模式会皱眉吗?
我与从事此业务20年的一位高级开发人员进行了讨论。他在安大略省以撰写博客而闻名。 他告诉我的事情很奇怪:他说,有一段代码是一场噩梦,因为它是从一本教科书中编写的,并不说明现实世界。将新字段添加到UI /数据库/数据层需要2-3个小时,而在他的代码中则需要30分钟。 另一件事是,他避免使用设计模式,因为大多数程序员都不了解它们,并且从维护的角度来看它们也不是很好。 还有一种想法是,加拿大的大多数Web开发人员都希望其数据模型继承自Data Layer类,而不是保持隔离状态。我问他:“将模型与数据层分开不是行业标准吗?” 他有时说,但是这里的大多数人不愿意这样做,因为这工作太多。 听起来他之所以不使用最佳实践进行编码,是因为这是一场维护噩梦,很少有员工了解(除了我自己),如果您需要在几天内推出新功能或新领域,工作起来会很慢。时间。 考虑到Stack Overflow主要鼓励人们遵循行业标准,听到这样的意见真是太奇怪了。我们是否被迫在几天之内不断推出新的领域和功能,以至于无法推断出足够灵活的坚实模式呢?这似乎是我从中了解的要点。 您如何看待这些陈述?

17
从不存在返回值的函数/方法中返回NULL或空值更好吗?
我在这里寻找建议。我正在努力在不存在返回值或无法确定返回值的情况下从方法返回NULL还是返回空值更好。 以以下两种方法为例: string ReverseString(string stringToReverse) // takes a string and reverses it. Person FindPerson(int personID) // finds a Person with a matching personID. 在中ReverseString(),我会说返回一个空字符串,因为返回类型是字符串,因此调用者期望得到。同样,通过这种方式,调用方将不必检查是否返回了NULL。 在中FindPerson(),返回NULL似乎更合适。无论是否new Person()返回NULL或空的Person Object(),调用者都必须在对其进行任何操作(如调用UpdateName())之前检查一下Person对象是否为NULL或为空。因此,为什么不只在此处返回NULL,然后调用方只需检查NULL。 还有其他人为此感到挣扎吗?任何帮助或见解表示赞赏。

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.