Questions tagged «design»

有关通过软件设计解决问题和计划解决方案的问题。

3
如何解决循环依赖?
我有三个相互循环依赖的类: TestExecuter执行TestScenario的请求,并使用ReportGenerator类保存报告文件。所以: TestExecuter依赖ReportGenerator生成报告 ReportGenerator取决于TestScenario和TestExecuter设置的参数。 TestScenario取决于TestExecuter。 无法弄清楚如何删除那些依赖项。 public class TestExecuter { ReportGenerator reportGenerator; public void getReportGenerator() { reportGenerator = ReportGenerator.getInstance(); reportGenerator.setParams(this.params); /* this.params several parameters from TestExecuter class example this.owner */ } public void setTestScenario (TestScenario ts) { reportGenerator.setTestScenario(ts); } public void saveReport() { reportGenerator.saveReport(); } public void executeRequest() { /* …

7
如果我没有很好的想法来实现功能该怎么办?[关闭]
我正在开发自己的应用程序,但遇到了麻烦。我必须实现一个功能,但是找不到实现该功能的好方法。我考虑了几天,没有好主意。搜索互联网并没有给我任何启发。 我需要继续前进,但我想知道什么是最好的: 多思考,多等待,然后继续寻找最佳方法 停止浪费时间,从不良的设计开始,用测试覆盖一切 你怎么看?如前所述,我正在开发自己的应用程序。我没有任何截止日期,但我也想尽快完成对应用程序的编码。
32 design 

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

2
如何设计可扩展的通知系统?[关闭]
我需要写一个通知系统管理员。 这是我的要求: 我需要能够在可能完全不同的不同平台上发送通知(例如,我需要能够发送SMS或电子邮件)。 有时,对于给定平台的所有收件人,通知可能是相同的,但是有时,可能是每个平台(或多个)每个收件人的通知。 每个通知可以包含特定于平台的有效负载(例如,MMS可以包含声音或图像)。 系统需要可伸缩,我需要能够发送大量通知而不会导致应用程序或服务器崩溃。 这是一个分为两个步骤的过程,首先,客户可以输入消息并选择要发送到的平台,然后创建通知,以便稍后进行实时处理。 然后,系统需要将通知发送到平台提供商。 就目前而言,尽管我得到了一些结论,但是我不知道它的可扩展性或它是否是一个好的设计。 我有以下对象(使用伪语言): 通用Notification对象: class Notification { String $message; Payload $payload; Collection<Recipient> $recipients; } 如果我有1.000.000收件人,则以下对象的问题是什么?即使Recipient对象很小,也会占用太多内存。 我还可以为每个收件人创建一个通知,但是某些平台提供商要求我批量发送该通知,这意味着我需要定义一个包含多个收件人的通知。 每个创建的通知可以存储在诸如DB或Redis的持久性存储中。 稍后汇总此内容以确保其可伸缩性是否很好? 在第二步中,我需要处理此通知。 但是,如何区分通知给正确的平台提供商的通知呢? 我应该使用诸如MMSNotification扩展对象之类的对象abstract Notification吗?或类似的东西Notification.setType('MMS')? 为了允许同时处理大量通知,我认为像RabbitMQ这样的消息传递队列系统可能是正确的工具。是吗? 这将使我可以排队很多通知,并有几个工作人员弹出通知并进行处理。但是,如果我需要如上所述对收件人进行批处理怎么办? 然后我想象NotificationProcessor的,我我可以添加对象NotificationHandler的每个NotificationHandler将负责连接平台提供商和执行通知。 我也可以使用EventManager允许插入行为。 有任何意见或建议吗? 感谢您抽出宝贵的时间。 注意:我曾经使用过PHP,并且它可能是我选择的语言。 编辑 (根据morphunreal的答案) 您每秒发送多少消息(定义当前/初始级别,定义在重新设计之前系统应处理的最大级别) 系统具有哪些硬件限制(内存,CPU等可供系统使用) 硬件将如何扩展(即添加更多服务器,云计算等) 哪些语言/系统将生成通知? 它是我自己的事情,我负责以编程方式创建通知,但该通知是通过用户界面构建的。 生成器是否知道消息的收件人(?),还是通过其他某种方式提供消息(例如,某些警报类型的业务规则将发送给某些收件人) 应该可以为特定收件人,一组收件人(例如,使用标签系统)或整个平台创建通知。 是否有添加CC / BCC /阅读收据的业务规则 是。请注意,这实际上是特定于平台的,read或cc并非在所有平台上都可用。 …

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

18
开发人员应该反对不必要或有害的功能吗?
在讨论新功能(即非关键/可疑功能)时,开发人员的良好态度是什么? 假设您正在开发某种类似Java的语言,老板说:“我们需要指针,以便开发人员可以直接摆弄对象内存!” 开发人员应该否定这个想法,因为它增加了难以想象的复杂性和安全漏洞,还是应该执行所要求的操作? 这可能不是一个很好的例子,但是在灰色区域显示的内容又如何呢?例如添加破坏工作流程的按钮,或违反程序的内部结构等? 对于普通程序员而言,最佳的“可以做”与“不能做”分配是什么? 编辑:问题不是关于一个坏老板:D 我更感兴趣的是人们如何处理新问题,这些新问题增加了很多数量的问题,而同时又可能微不足道。 一般态度应该是: 是的,我们会做,解决复杂性 也许 不,一般的返工和含义不能证明变更的合理性 一个好的开发者应该怎么做?
32 design 

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

10
假设任何物理量都可以用64位整数表示而没有上溢或下溢是否合理?
如果(low + high) > INT_MAX(http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html),则JDK中的原始二进制搜索算法使用32位整数,并且存在溢出错误。。 如果我们使用(带符号的)64位整数重写相同的二进制搜索算法,是否可以假设它low + high永远不会超过INT64_MAX,因为实际上不可能有10 ^ 18字节的内存? 当使用(有符号的)64位整数表示物理量时,是否假定不会发生下溢和溢出是否合理?

5
设计自上而下还是自下而上是更可取的?
据我了解,自上而下的设计是通过将抽象的高级概念细化为较小的混凝土和易于理解的部分,直到定义了最小的构建块。另一方面,自下而上定义了较低级别的部分,然后逐渐构建较高级别的块,直到形成整个系统。 实际上,最好将两种方法结合起来:从高级规范开始,以完全指定领域知识,其关系和约束。一旦清楚地了解了问题,便会创建最小的构建块来构建系统。 过程: 创建需求规范 创建设计规范(带有图表) 实行 交付 重复(在迭代开发中,我们不重复每个阶段的全部工作,而是重复每个阶段的一点工作,并每天开会以满足客户的动态需求) 看起来对我来说是完全正常的(以规格作为计划)。它有其缺陷,但这就是为什么我们要进行迭代开发:为什么要花时间在一个阶段上,而不是花时间进行需求分析,以研究领域知识中可能发生变化的所有可能事物(可能每天),而是进行一些分析,进行一些设计然后实施。 另一种方法是,每次迭代都是一种小型瀑布式的方式,在几天(或一周)内进行分析。设计同样如此。其余时间用于实施。自上而下的方法与迭代开发相结合有天生的错误吗? Paul Graham 在他的论文《自下而上编程》中似乎鼓励完全自下而上地构建,或者鼓励自下而上地对其进行编程,但是不建议进行需求分析/设计阶段: 经验丰富的Lisp程序员对程序进行了不同的划分。除自上而下的设计外,它们还遵循可称为自下而上的设计的原则-更改语言以适应问题。 就我所知,他的意思是Lisper仍然执行自上而下的设计,但程序自下而上,是真的吗?他写道: 值得强调的是,自下而上的设计并不意味着仅以不同的顺序编写相同的程序。自下而上工作时,通常会得到不同的程序。您将获得一种具有更多抽象运算符的更大语言,以及一个用它编写的较小程序,而不是一个单一的整体程序。取而代之的是门,而不是门。 这是否意味着在用Lisp编写程序期间,您最终会获得通用工具?
31 design  c++  lisp 

15
程序员可以从建筑业中学到什么?[关闭]
在与同事讨论软件设计和开发原理时,我注意到类比的最常见来源之一是建筑行业。我们构建软件,并将设计和结构视为体系结构。 学习(或教导)的最佳方法之一是通过分析类比- 从构造中还能得出哪些其他类比? (是否已经在软件中普遍使用)。 请提供有关编程概念与构造概念的相似之处的描述或您的个人经验。 [ 取材于艺术和人文科学的编程概念学分]

5
当不需要属性之一时实现接口
很简单。我正在实现一个接口,但是该类没有一个属性是必需的,实际上,不应使用该属性。我最初的想法是做一些类似的事情: int IFoo.Bar { get { raise new NotImplementedException(); } } 我想这本身没有错,但是感觉并不“正确”。有人遇到过类似情况吗?如果是这样,您是如何处理的?

5
记录产品设计决策依据的有效方法是什么?
在我们公司,我们不使用任何产品设计文件。我们共有三名员工,因此所有产品设计讨论都当面或在Slack上进行。(我们还在基本的Slack软件包上,该软件包仅允许查看最新消息。) 我们的产品仍处于早期阶段,我们经常重新访问几个月前确定的设计元素。 我们经常痛苦地面临的一个问题是忘记了为什么要做出产品设计决策。这导致浪费了数小时来重读相同的地面。 我们如何有效记录设计决策背后的基本原理? 我们的工作流程基于Pivotal Tracker。我想到的一种解决方案是,将所有相关设计决策的依据记录为对用户故事本身的评论,但这似乎并不可靠。 要100%清楚:我不是在谈论代码的设计。我说的是由代码实现的产品设计。换句话说,我不是在谈论诸如“我们应该使用合成而不是多重继承来构造这个类吗?”之类的决策。我正在谈论诸如“我们应该要求用户在登录之前确认用户的电子邮件地址吗?”之类的决定。 该文档的目的是允许企业查看做出决策的原因的记录,以帮助做出有关同一主题的进一步决策。

9
设计一个类以将整个类作为参数而不是单个属性
举例来说,假设您有一个应用程序,该应用程序具有广泛共享的类,称为User。此类公开有关用户,其ID,名称,对每个模块的访问级别,时区等所有信息。 用户数据显然在整个系统中得到了广泛的引用,但是无论出于何种原因,都对系统进行了设置,因此,我们不是在将用户对象传递到依赖于该对象的类中,而是从其中传递了各个属性。 需要用户ID的类仅需要GUID userId作为参数,有时我们可能还需要用户名,因此将其作为单独的参数传递。在某些情况下,这将传递给各个方法,因此这些值根本不会保存在类级别。 每当我需要从User类访问不同的信息时,我都必须通过添加参数进行更改,而在不适合添加新的重载的地方,我也必须更改对方法或类构造函数的每个引用。 用户只是一个例子。这在我们的代码中得到了广泛的实践。 我认为这违反了开放/封闭原则,对吗?不仅是更改现有类的行为,而且是首先设置它们,以便将来很有可能需要进行广泛的更改吗? 如果我们只是传入User对象,则可以对正在使用的类进行一些小的更改。如果必须添加参数,则可能不得不对类的引用进行数十次更改。 这种做法是否违反了其他任何原则?依赖倒置也许?尽管我们没有引用抽象,但是只有一种类型的用户,因此并没有真正需要User界面的需求。 是否还有其他违反非Solid的原则,例如基本的防御性编程原则? 我的构造函数应如下所示: MyConstructor(GUID userid, String username) 或这个: MyConstructor(User theUser) 发表编辑: 已经建议在“密码或对象?”中回答问题。这并未回答以下问题的问题:无论哪种方式的决定都会如何影响遵循SOLID原则的尝试,而SOLID原则是此问题的核心。
30 java  c#  design  solid 

10
假设有一群马,我如何找到所有独角兽的平均角长?
上面的问题是我在遗留代码中遇到的一个常见问题的抽象示例,或更准确地说,是以前解决该问题的尝试所导致的问题。 我可以想到至少一种旨在解决此问题的.NET框架方法,例如该Enumerable.OfType<T>方法。但是,您最终最终在运行时询问对象的类型这一事实与我不对。 除了问每匹马:“你是独角兽吗?” 还想到以下方法: 尝试获取非独角兽角的长度时引发异常(暴露了不适用于每匹马的功能) 返回一个非独角兽号角长度的默认值或魔术值(需要在所有想要对一组全都是非独角兽的马进行角统计的代码中添加默认检查) 消除继承,并在马上创建一个单独的对象,该对象告诉您马是否为独角兽(这可能会将同一问题推下一层) 我觉得最好用“不回答”来回答。但是,您如何解决这个问题?如果取决于这个问题,您的决定的背景是什么? 对于这个问题是否仍然存在于功能代码中(或者也许仅存在于支持可变性的功能语言中),我也会感兴趣。 这被标记为以下问题的可能重复: 如何避免向下转换? 该问题的答案假设一个人拥有一个HornMeasurer,必须进行所有的号角测量。但这是对基于平等原则而形成的代码库的强加,即每个人都应该可以自由地测量马的角。 缺少a时HornMeasurer,可接受的答案的方法反映了上面列出的基于异常的方法。 关于马和独角兽都是马,还是独角兽是马的神奇亚种,评论中也有些困惑。两种可能性都应该考虑-也许一个比另一个更可取吗?

2
python工厂函数最佳实践
假设我有一个foo.py包含类的文件Foo: class Foo(object): def __init__(self, data): ... 现在,我想添加一个函数,该函数Foo以某种方式从原始源数据创建对象。我应该将其作为Foo中的静态方法还是另一个单独的函数? class Foo(object): def __init__(self, data): ... # option 1: @staticmethod def fromSourceData(sourceData): return Foo(processData(sourceData)) # option 2: def makeFoo(sourceData): return Foo(processData(sourceData)) 我不知道方便用户使用是否更重要: foo1 = foo.makeFoo(sourceData) 还是在方法和类之间保持清晰的耦合更重要: foo1 = foo.Foo.fromSourceData(sourceData)
30 design  python 

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.