Questions tagged «design-patterns»

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

4
在模型中放入诸如“ FullName”或“ FormattedPhoneNumber”之类的吸气剂是“一种模式的气味”吗?
我正在开发ASP.NET MVC应用程序,并且已经养成了将看起来有用且方便的吸气剂放入模型/实体类的习惯。 例如: public class Member { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string PhoneNumber { get; set; } public string FullName { get { return FirstName + " " + LastName; } } …

9
设计模式:我应该学习它们吗?[关闭]
关闭。这个问题是题外话。它当前不接受答案。 想改善这个问题吗? 更新问题,使它成为软件工程堆栈交换的主题。 4年前关闭。 因此,背对背问两个问题有点奇怪,但是它们并不太相关,我也不想将它们结合在一起,但是我保证,我不是在发垃圾邮件! 无论如何,我是一个刚上大学的应届毕业生,我的学业只涉及设计模式...我们实施了一些简单的模式,涉及了更复杂的事实,并被告知如果我们去GoF书,想了解更多。我的问题是,值得学习GoF书中的模式吗?在我看来,尝试使问题适合经典模式似乎总是违反直觉的,但是很显然,这本书和这些模式都是有名的。它们显示出来足以让我学习吗? 再次感谢!

1
根据语法编写词法分析器时应遵循的步骤是什么?
在阅读有关语法,词法分析器和语法分析器的澄清问题的答案时,答案指出: BNF语法包含词法分析和解析所需的所有规则。 这对我来说有点奇怪,因为直到现在,我一直认为词法分析器根本不基于语法,而解析器则很大程度上基于语法。在阅读了许多有关编写词法分析器的博客文章之后,我得出了这个结论,而从来没有人使用1 EBNF / BNF作为设计基础。 如果词法分析器以及解析器都基于EBNF / BNF语法,那么如何使用该方法创建词法分析器呢?也就是说,如何使用给定的EBNF / BNF语法构造词法分析器? 我见过很多,很多的职位,应对写的用EBNF / BNF作为指导或蓝图解析器,但我已经遇到没有到目前为止,显示与词法分析器的设计相当。 例如,采用以下语法: input = digit| string ; digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ; string = '"', { all characters - '"' …

6
什么是最简单的人类可读配置文件格式?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 5年前关闭。 当前配置文件如下: mainwindow.title = 'test' mainwindow.position.x = 100 mainwindow.position.y = 200 mainwindow.button.label = 'apply' mainwindow.button.size.x = 100 mainwindow.button.size.y = 30 logger.datarate = 100 logger.enable = True logger.filename = './test.log' 使用python将其读取到嵌套字典中: { 'mainwindow':{ 'button':{ 'label': {'value':'apply'}, ... }, 'logger':{ datarate: {'value': 100}, enable: {'value': True}, filename: {'value': './test.log'} }, …

6
DDD符合OOP:如何实现面向对象的存储库?
DDD存储库的典型实现看起来不太像面向对象,例如一种save()方法: package com.example.domain; public class Product { /* public attributes for brevity */ public String name; public Double price; } public interface ProductRepo { void save(Product product); } 基础架构部分: package com.example.infrastructure; // imports... public class JdbcProductRepo implements ProductRepo { private JdbcTemplate = ... public void save(Product product) { JdbcTemplate.update("INSERT INTO …

1
使用朋友类封装C ++中的私有成员函数-好的做法还是滥用?
因此,我注意到可以通过执行以下操作来避免将私有函数放在标头中: // In file pred_list.h: class PredicateList { int somePrivateField; friend class PredicateList_HelperFunctions; public: bool match(); } // In file pred_list.cpp: class PredicateList_HelperFunctions { static bool fullMatch(PredicateList& p) { return p.somePrivateField == 5; // or whatever } } bool PredicateList::match() { return PredicateList_HelperFunctions::fullMatch(*this); } 私有函数永远不会在标头中声明,并且导入标头的类的使用者永远不需要知道它的存在。如果helper函数是模板,则这是必需的(替代方法是将完整的代码放在标头中),这就是我“发现”它的方式。如果添加/删除/修改私有成员函数,则不需要重新编译包含头文件的每个文件的另一个好处。所有专用功能都位于.cpp文件中。 所以... 这是一个众所周知的设计模式吗? 对我来说(来自Java / C#背景并且自己学习C …

2
当应用的某些部分用不同的语言编写时,如何避免数据结构重复?
例如,假设您正在用Java编写应用程序。 您的应用程序与使用Python编写的API服务器进行通信。 Python服务器与SQL数据库进行通信。 您还拥有一个用JavaScript编写的应用程序网站。 使用4种不同的语言,很容易以4次不同的时间重复基本相同的数据结构。 例如,User类型可能看起来像这样(伪代码): type User { integer id; string name; timestamp birthday; } 项目的每个部分都需要某种形式的表示User。Java和Python部分将需要两个不同的class声明。数据库将需要一个User表声明。前端站点也需要代表一个站点User。 重复此类型4次确实违反了“ 请勿重复自己”原则。还有一个问题是,如果User更改了类型,则需要在项目的每个不同部分中重复这些更改。 我知道Google的protobuf库为该问题提供了一种解决方案,您可以使用特殊的语法编写数据结构,然后该库以多种不同的编程语言为您生成结构声明。但这仍然没有解决必须为您的类型重复验证逻辑的问题。 是否有人对此有任何建议或链接到书籍/博客文章?

4
类应如何向用户传达其实现的方法子集?
情境 Web应用程序IUserBackend使用以下方法定义用户后端接口 getUser(uid) createUser(uid) deleteUser(uid) setPassword(uid,密码) ... 不同的用户后端(例如LDAP,SQL等)实现此接口,但并非每个后端都能做所有事情。例如,一个具体的LDAP服务器不允许该Web应用程序删除用户。因此LdapUserBackend实现的类IUserBackend将不会实现deleteUser(uid)。 具体的类需要向Web应用程序传达允许Web应用程序与后端用户进行的操作。 已知解决方案 我已经看到了一个解决方案,其中IUserInterface具有一种implementedActions方法,该方法返回一个整数,该整数是操作按位与所请求的操作进行“与”运算的结果: function implementedActions(requestedActions) { return (bool)( ACTION_GET_USER | ACTION_CREATE_USER | ACTION_DELTE_USER | ACTION_SET_PASSWORD ) & requestedActions) } 哪里 ACTION_GET_USER = 1 ACTION_CREATE_USER = 2 ACTION_DELETE_USER = 4 ACTION_SET_PASSWORD = 8 .... = 16 .... = 32 等等 因此,Web应用程序根据需要设置位掩码,并implementedActions()使用布尔值回答是否支持它们。 意见 在我看来,这些位操作看起来像C时代的遗物,就干净的代码而言,不一定易于理解。 …

5
寻找最适合圈子的人
下面是一个示例图像,如果我在中间有一个白点,并且我想找到所有可能存在的红色圆圈,则该蓝色圆圈的位置可能最近(显然是我放置它的位置) 。如何找到该位置? 对我来说,性能并不是此应用程序的主要问题。

8
使用一种可以在客户之间变化的方法对类进行正确的设计
我有一个用于处理客户付款的类。除了一个类(用于计算(例如)客户的用户欠款额的)方法外,对于每个客户而言,此类中的一种方法均是相同的。各个客户之间的差异可能很大,并且由于存在许多自定义因素,因此没有简单的方法来捕获诸如属性文件之类的计算逻辑。 我可以编写难看的代码,以根据customerID进行切换: switch(customerID) { case 101: .. do calculations for customer 101 case 102: .. do calculations for customer 102 case 103: .. do calculations for customer 103 etc } 但这需要在我们每次获得新客户时都重新构建班级。有什么更好的方法? [编辑]“重复”的文章完全不同。我不是在问如何避免使用switch语句,而是在寻求最适合这种情况的现代设计-如果我想编写恐龙代码,可以使用switch语句解决。此处提供的示例是通用的,无济于事,因为它们本质上是在说“嘿,在某些情况下,此开关工作得很好,而在另一些情况下,则效果很好。” [编辑]我决定采用排名靠前的答案(为实现标准接口的每个客户创建一个单独的“客户”类),原因如下: 一致性:我可以创建一个接口,以确保所有Customer类都可以接收并返回相同的输出,即使是由其他开发人员创建的 可维护性:所有代码都使用相同的语言(Java)编写,因此无需其他任何人学习单独的编码语言来维护应该是简陋的功能。 重用:如果在代码中出现了类似的问题,我可以重用Customer类来容纳许多方法来实现“自定义”逻辑。 熟悉:我已经知道如何执行此操作,因此我可以快速完成它,然后继续处理其他更紧迫的问题。 缺点: 每个新客户都需要编译新的Customer类,这可能会增加我们编译和部署更改的方式的复杂性。 每个新客户都必须由开发人员添加-支持人员不能只是将逻辑添加到属性文件之类的东西中。这不是理想的选择……但是后来我也不确定支持人员将如何写出必要的业务逻辑,尤其是当它很复杂且有很多例外时(很可能)。 如果我们增加许多新客户,它将无法很好地扩展。这是不期望的,但是如果确实发生了,我们将不得不重新考虑代码的许多其他部分以及这一部分。 对于您感兴趣的人,可以使用Java Reflection按名称调用类: Payment payment = getPaymentFromSomewhere(); try { String …


3
了解助焊剂模式
我实际上正在研究流量模式,关于商店我有些不了解。 他们到底是什么? 我已经阅读了许多文章,似乎与该领域有关。 这是否意味着这是与api调用或后端调用相关的“抽象”部分? 对我来说不是很清楚。 编辑:可能与角度工厂相同吗?获取远程数据,执行业务任务或存储某些应用程序状态(例如,当前连接的用户)?

2
为什么“拉链”会忽略该系列的悬空尾巴?
C#,Scala,Haskell,Lisp和Python具有相同的zip行为:如果一个集合较长,则尾部将被忽略。 也可能会引发异常,但是我没有听说使用这种方法的任何语言。 这让我感到困惑。有人知道这样做的原因zip吗?我猜对于新语言来说,是这样做的,因为其他语言都是这样做的。但是,根本原因是什么? 我在这里问的是事实性的,基于历史的问题,而不是有人是否喜欢它,或者这是好是坏的方法。 更新:如果有人问我该怎么做,我会说-引发异常,这与对数组建立索引非常相似(尽管“旧”语言做了各种魔术,如何处理越界索引,UB,扩展数组,等等)。

2
我应该如何处理记录器故障?
在公司的一些应用程序中,我们使用自定义记录器。它相当健壮,尽管将来我们可能会用NLog之类的东西来代替它。记录器的任务之一是记录应用程序中遇到的任何异常。 我一直担心的一个问题是,记录器中的异常处理允许出现静默故障。也就是说,如果未针对给定的异常编写日志(由于记录器中的错误),那么我应该如何处理该异常并(以某种方式)将异常记录到记录器本身中? 假设WriteLog函数引发异常。我应该尝试多次调用该函数还是直到不引发异常之前?我是否应该尝试使用记录器编写引发的异常(这很可能会导致异常完全消失……)?除了第一次实现自定义记录器时,我很幸运没有遇到这种情况。另一方面,我目前无法知道记录器是否未能记录应用程序异常(由于其自身的异常)。 我已经尝试过在线和在一些SE网站上进行搜索,但是到目前为止,由于所有帖子都处理记录器中的错误(但不记录潜在的异常以及如何记录它们)或记录器外部的异常,到目前为止,这种方法是徒劳的。

3
在代码中生成Excel(xlsx)文件的良好设计模式是什么?
有关更多信息,请参见底部的我的更新。 有时,我有一些项目必须将某些数据输出为Excel文件(xlsx格式)。该过程通常是: 用户单击我的应用程序中的一些按钮 我的代码运行数据库查询并以某种方式处理结果 我的代码使用Excel com互操作库或某些第三方库(例如Aspose.Cells)生成* .xlsx文件 我可以轻松地找到有关如何在线执行此操作的代码示例,但是我正在寻找一种更强大的方法来执行此操作。我希望我的代码遵循一些设计原则,以确保我的代码可维护且易于理解。 这是我最初尝试生成xlsx文件的样子: var wb = new Workbook(); var ws = wb.Worksheets[0]; ws.Cells[0, 0].Value = "Header"; ws.Cells[1, 0].Value = "Row 1"; ws.Cells[2, 0].Value = "Row 2"; ws.Cells[3, 0].Value = "Row 3"; wb.Save(path); 优点:不多。它可以工作,所以很好。 缺点: 单元格引用是经过硬编码的,因此在我的代码中到处都是乱七八糟的数字。 如果不更新许多单元格引用,则很难添加或删除列和行。 我需要学习一些第三方库。一些库的使用方式与其他库一样,但是仍然存在问题。我有一个问题,com互操作库使用基于1的单元格引用,而Aspose.Cells使用基于0的单元格引用。 这是一种解决上面列出的缺点的解决方案。我想将数据表当作自己的对象,可以在不深入了解单元操作和不干扰其他单元格引用的情况下随意移动和更改数据。这是一些伪代码: var headers = new Block(new string[] …

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.