Questions tagged «design»

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

6
有关如何传播面向对象实践的技巧
关闭。这个问题是题外话。它当前不接受答案。 想改善这个问题吗? 更新问题,以使它成为软件工程堆栈交换的主题。 4年前关闭。 我为一家拥有250名开发人员的中型公司工作。不幸的是,许多应用程序都陷入了过程性思维之中,一些团队不断交付大型事务脚本应用程序,而实际上该应用程序包含丰富的逻辑。他们还无法管理设计依赖性,最终得到的服务依赖于另一批大量的服务(“泥浆大球”的一个清晰示例)。 我的问题是:您能否建议如何传播这种知识? 我知道问题的表面在于这些应用程序的体系结构和设计不佳。另一个问题是,有些开发人员反对编写任何类型的测试。 我正在做一些改变这种情况的事情(但是我要么失败,要么改变太小了) 关于设计原理(SOLID,简洁代码等)的运行演示。 关于TDD和BDD的研讨会。 指导团队(这包括使用声纳,findbug,jdepend和其他工具)。 IDE和重构讲座。 我将来打算做的几件事(但我担心它们可能不好) 组成一个由OO传播家组成的团队,他们在不同的团队中传播OO的思维方式(这些人每隔几个月就要更换团队)。 运行设计审查会议,以批评设计并提出改进建议(即使由于时间限制而未完成改进,我认为这可能会很有用) 。 我在我的教练团队中发现的一件事是,一旦我离开他们,他们就会恢复到原来的做法。我知道我不会花很多时间陪伴他们,通常只有一个月。因此,无论我在做什么,它都不会粘住。 对不起,这个问题让我无奈,但写这个的替代方法是打我的头,直到我晕倒。

3
您如何分辨是使用复合模式还是树结构,还是第三个实现?
我有两种客户端类型,即“ 观察者 ”类型和“ 主题 ”类型。它们都与组的层次结构相关联。 观察者将从不同层次中与其关联的组中接收(日历)数据。通过合并尝试收集数据的组的“父”组中的数据(每个组只能有一个父组)来计算此数据。 主题将能够在与其关联的组中创建数据(观察者将接收)。当在一个组中创建数据时,该组的所有“子级”也将拥有该数据,他们将能够为数据的特定区域制作自己的版本,但仍链接到创建的原始数据(在在我的特定实现中,原始数据将包含时间段和标题,而子组则为直接链接到其各自组的接收者指定其余数据。 但是,当主体创建数据时,必须检查所有受影响的观察者是否有与此冲突的数据,据我所知,这意味着庞大的递归功能。 因此,我认为这可以归纳为以下事实:我需要具有一个可以在其中上下移动的层次结构,并且某些地方必须能够将它们作为一个整体来对待(基本上是递归)。 另外,我不仅针对可行的解决方案。我希望找到一种相对容易理解的解决方案(至少在体系结构方面),并且足够灵活,以便将来能够轻松接收其他功能。 是否有解决此问题或类似层次结构问题的设计模式或良好实践? 编辑: 这是我的设计: “ Phoenix”类以这种方式命名,因为我还没有想到合适的名称。 但是除此之外,我需要能够为特定的观察者隐藏特定的活动,即使这些活动通过组与之相连。 有点题外话: 就我个人而言,我认为我应该可以将这个问题分解为较小的问题,但这使我无所适从。我认为这是因为它涉及多个相互不关联的递归功能,以及需要以不同方式获取信息的不同客户端类型。我真的不能把头缠住它。如果有人能指导我如何更好地封装层次结构问题,我也将很高兴收到这一消息。

9
如何拆分紧密联系的大型课程?
我有一些巨大的类,它们包含超过2k行代码(并且还在不断增长),如果可能的话,我希望对其进行重构,以实现更加轻巧和简洁的设计。 它之所以如此之大,主要是因为这些类处理大多数方法都需要访问的一组映射,并且方法之间相互联系紧密。 我将举一个非常具体的示例:我有一个名为的类Server来处理传入消息。它有类似的方法joinChatroom,searchUsers,sendPrivateMessage等所有这些方法操纵映射,如users,chatrooms,servers,... 如果我可以有一个类来处理有关Chatrooms的消息,另一个可以处理所有有关Users的消息,等等,这也许会很好,但是这里的主要问题是我需要在大多数方法中使用所有地图。因此,Server由于它们都依赖于这些通用映射,并且方法之间相互联系紧密,因此它们现在都属于该类。 我需要创建一个类Chatrooms,但要引用其他每个对象。类的用户再次引用所有其他对象,等等。 我觉得我做错了什么。

4
我们应该重命名重载的方法吗?
假定包含以下方法的接口: Car find(long id); List<Car> find(String model); 像这样重命名它们更好吗? Car findById(long id); List findByModel(String model); 实际上,使用此API的任何开发人员都无需查看接口即可知道初始find()方法的可能参数。 所以我的问题更笼统:在代码中使用重载方法有什么好处,因为它会降低可读性?

4
是否应该坚持一致性而不是编程约定?
在设计类时,是否应该在行为习惯上优于常规编程实践?举一个具体的例子: 一个常见的约定是:如果一个类拥有一个对象(例如,它创建了一个对象),则它负责在对象完成后对其进行清理。.NET中的一个具体示例是,如果您的类拥有一个IDisposable对象,则应在其生命周期结束时对其进行处置。如果您不拥有它,请不要触摸它。 现在,如果我们看一下StreamWriter.NET 中的类,则可以在文档中找到在关闭/处置它时关闭基础流的信息。如果在StreamWriter编写器创建基础文件流并因此需要关闭它时通过传入文件名实例化的情况下这是必需的。但是,也可以传入作者也关闭的外部流。 这使我烦恼了很多次(是的,我知道您可以制作一个非关闭的包装器,但这不是重点),但是显然微软已经做出决定,无论来自何处,始终关闭流是更加一致的。 当我在一个类中遇到这种模式时,我通常会创建一个ownsFooBar标志,如果FooBar通过构造函数注入该标志,则将其设置为false;否则,将其设置为true。这样,当调用者显式传递实例时,将其清除的责任传递给了调用者。 现在我想知道一致性是否应该优于最佳实践(或者我的最佳实践不是那么好)吗?有反对意见吗? 编辑以澄清 “一致性”的意思是:类的一致行为总是获取所有权(并关闭流)与“最佳实践”相比,仅当创建对象或显式转移所有权时才获取对象的所有权。 例如,它令人眼花ying乱: 假设您有两个给定的类(来自某个第三方库),它们接受一个流以对其进行处理,例如创建和处理一些数据: public class DataProcessor { public Result ProcessData(Stream input) { using (var reader = new StreamReader(input)) { ... } } } public class DataSource { public void GetData(Stream output) { using (var writer = new StreamWriter(output)) { .... } } …
14 design  .net 

8
在什么情况下流程图仍然是有价值和有用的工具?
刚开始编程时,我非常依赖流程图(和打印机间距图)。当我在COBOL课堂上时,直到我的流程图被教员批准后,我才能开始编写任何代码。那时,我必须为所有内容制作流程图。 今天,二十五年后,我发现自己只绘制了两种情况。逻辑很棘手的非常具体的算法或非常笼统的概念,以确保我按正确的顺序定义了所有重要步骤。 我只是忽略了流程图的其他用例吗?

10
呈现出可怕的设计时该怎么办?
我们公司制作网站。我们还设计网站。但是有时我们的客户会带来他/她自己的设计。这通常是由内部设计师制作的,或者与其他设计相同。但是,有时这些设计看起来很糟糕。我说的真的是不专业,不平衡,不冷静。但是客户确实想要这种设计。我真的不喜欢使用如此糟糕的设计。它带走了编码的所有乐趣。您编码。您检查演示。效果很好。看起来糟透了。只是不好玩。 最终客户可能会很高兴,但是1)我对最终产品不感到自豪; 2)社区看到您“开发”丑陋的网站,这对您的形象不利。 有人遇到这种东西吗?你有什么建议吗? 我一直在想: 阻止这些客户。如果有人设计了“自己的”设计,请先看看。然后以某种方式礼貌地拒绝。缺点:您失去了客户。 创建一个新的设计。让我们的内部设计师完成一件非常酷的事情。缺点:客户需要为此付费(无需索取),否则将被拒绝,公司损失时间=金钱。如果您突然提出新的设计,这可能是一种侮辱。他们的设计师肯定不会喜欢。 在网站底部放置明确的免责声明:XXXXX的网站设计,美国的网站开发。帮助社区(如果人们注意),但不会带来不安感。
14 design 

3
如何为Winforms解决方案设置MVP?
我过去曾经使用过MVP和MVC,我更喜欢MVP,因为我认为它可以更好地控制执行流程。 我已经创建了我的基础结构(数据存储/存储库类),并且在对示例数据进行硬编码时可以毫无问题地使用它们,因此现在我转向GUI并准备我的MVP。 A节 我已经看到MVP使用视图作为入口点,也就是说,在视图构造方法中,它创建了演示者,该演示者又创建了模型,并根据需要连接事件。 我还以演示者为切入点,在其中创建了视图,模型和演示者,然后在其构造函数中为该演示者提供了视图和模型对象以关联事件。 与2中一样,但是模型没有传递给演示者。相反,该模型是一个静态类,在其中调用方法并直接返回响应。 B区 在使视图和模型保持同步方面,我已经看到了。 每当视图中的值发生更改时,即TextChanged.Net / C#中的事件。这会触发一个DataChangedEvent传递到模型中的,以使其始终保持同步。在模型发生变化的地方(即它侦听的后台事件),然后通过引发的相同想法来更新视图DataChangedEvent。当用户想要提交更改SaveEvent时,它将触发,并进入模型进行保存。在这种情况下,模型将模仿视图的数据并处理动作。 与#b1相似,但是视图并非始终与模型同步。相反,当用户想要提交更改时,将SaveEvent被解雇,演示者获取最新的详细信息并将其传递到模型中。在这种情况下,除非需要对视图数据进行操作,否则模型将不知道视图数据,在这种情况下,将传递所有必需的详细信息。 C区 在视图中显示业务对象,即不是原始数据的对象(MyClass)(int,double) 该视图具有将显示为域/业务对象的所有数据的属性字段。例如,view.Animals公开一个IEnumerable<IAnimal>属性,即使视图将它们处理到TreeView中的Nodes中。然后对于选定的动物,它将SelectedAnimal作为IAnimal属性公开。 该视图不了解域对象,它仅公开图元/框架(.Net / Java)包含的对象类型的属性。在这种情况下,演示者将把适配器对象传递给域对象,然后适配器将给定的业务对象转换为视图上可见的控件。在这种情况下,适配器必须有权访问视图上的实际控件,而不仅仅是任何视图,因此会变得更加紧密。 D区 用于创建单个控件的多个视图。即,您有一个具有简单模型的复杂视图,例如保存不同类型的对象。您可以在侧面有一个菜单系统,每单击一个项目就会显示相应的控件。 您创建一个巨大的视图,其中包含通过视图界面公开的所有单个控件。 您有几种看法。您有一个菜单视图和一个空白面板。该视图创建所需的其他视图,但不显示它们(visible = false),该视图还为其包含的每个视图(即子视图)实现接口,因此可以向一个演示者公开。空白面板中将填充其他视图(Controls.Add(myview))和((myview.visible = true)。这些“子”视图中引发的事件由父视图处理,父视图又将事件传递给演示者,反之亦然,以将事件提供给子元素。 每个视图(无论是主要父视图还是较小的子视图)均连接到自己的演示者和模型中。您可以从文化上将视图控件放到现有的表单中,它将具备功能,只需将其连接到幕后的演示者中即可。 E节 如果所有内容都具有接口,那么现在基于以上示例中MVP的完成方式,由于它们可能不是交叉兼容的,因此将影响此答案。 一切都有界面,视图,演示者和模型。然后,显然每个都有具体的实现。即使您只有一个具体的视图,模型和演示者。 视图和模型具有接口。这允许视图和模型不同。演示者创建/获得视图和模型对象,并且仅用于在它们之间传递消息。 仅视图具有界面。该模型具有静态方法,不会创建,因此不需要接口。如果需要其他模型,则演示者将调用一组不同的静态类方法。由于模型是静态的,因此与演示者没有链接。 个人想法 从我介绍的所有不同变体中(大多数我可能已经以某种形式使用过),我确信还有更多。我更喜欢A3,因为它可以使业务逻辑在MVP之外可重用,而B2则可以减少数据重复和触发事件。C1用于不添加其他类,请确保将少量非单元可测试的逻辑放入视图中(如何可视化域对象),但是可以对其进行代码审查,也可以在应用程序中简单地对其进行查看。如果逻辑很复杂,我会同意一个适配器类,但并非在所有情况下都同意。对于D部分,我觉得D1创建的视图对于菜单示例来说至少太大了。我以前用过D2和D3。D2的问题是,您最终不得不编写大量代码才能将事件往返于演示者与演示者之间路由到正确的子视图,并且其拖放操作不兼容,每个新控件都需要更多接线才能支持单个演示者。D3是我的首选,但是即使视图恰好非常简单或不需要重用,D3仍会作为演示者和模型添加更多类来处理该视图。我认为根据情况,D2和D3的混合效果最好。对于E部分,我认为具有接口的所有内容都可能过头了,因为我已经对域/业务对象进行了此操作,因此这样做通常不会在“设计”中看到任何优势,但它确实有助于在测试中模拟对象。我个人认为E2是经典的解决方案,尽管我以前在2个项目中使用过E3。我认为根据情况,D2和D3的混合效果最好。对于E部分,我认为具有接口的所有内容都可能会过时了,我已经对域/业务对象进行了此操作,并且这样做通常不会在“设计”中看到任何优势,但是它确实有助于在测试中模拟对象。我个人认为E2是经典的解决方案,尽管我以前在2个项目中使用过E3。我认为根据情况,D2和D3的混合效果最好。对于E部分,我认为具有接口的所有内容都可能会过时了,我已经对域/业务对象进行了此操作,并且这样做通常不会在“设计”中看到任何优势,但是它确实有助于在测试中模拟对象。我个人认为E2是经典的解决方案,尽管我以前在2个项目中使用过E3。 题 我是否正确实施MVP?有正确的方法吗? 我已经读过Martin Fowler的著作,其中有很多变化,而且我还记得当我刚开始做MVC时,我理解了这个概念,但是最初无法确定切入点在哪里,一切都有自己的功能,但是控制和创建原始作品的是什么MVC对象集。

5
为什么我们不能更有效地捕获软件设计?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 4年前关闭。 作为工程师,我们所有人都“设计”人工制品(建筑物,程序,电路,分子...)。那是一个活动(动词设计),产生某种结果(动词设计)。 我认为我们都同意,名词设计与工件本身是不同的实体。 软件业务(实际上,在任何需要增强生成的产品工件的业务中)的关键活动是了解“设计(名词)”。但是,作为一个社区,我们似乎在记录它方面完全失败了,这可以从人们重新发现有关其代码基础的事实的大量努力中得到证明。让某人向您展示他们的代码设计,然后看看您得到了什么。 我认为软件设计具有以下特点: 一个明确的规范,说明该软件应该做什么以及其性能如何 代码的显式版本(这部分很简单,每个人都拥有) 关于代码的每个部分如何用于实现规范的说明(例如,规范片段和代码片段之间的关系) 一个理由,为什么代码是事情是这样的(例如,为什么一个特定的选择,而不是另一个) 不是设计就是代码的特定视角。例如,[不特别说明] UML图不是设计。相反,它们是可以从代码派生的属性,或者可以说是希望从代码派生的属性。但是作为一般规则,您不能从UML派生代码。 为什么经过50多年的软件构建,为什么我们没有常规的方法来表达这一点?(请通过明确的示例与我自相矛盾!) 即使我们这样做,大多数社区似乎都非常关注于获取“代码”,以至于无论如何都会迷失于设计中。(恕我直言,直到设计成为工程的目的,从设计中提取出工件之后,我们才可以解决这个问题)。 您认为什么是记录设计的方式(就我所描述的而言)?明确引用论文会很好。为什么您认为特定的和一般的方法没有成功?我们该如何改变呢? [我有自己的想法,这些使上面的项目符号观点更加充实,但是我对其他人的回答很感兴趣……而且很难实施我的方案[[也许这是真正的问题:-]]] EDIT 2011/1/3:一个回答线程暗示“文档”(大概是文本的,尤其是非正式的)可能就足够了。我想我应该澄清一下,我不相信这一点。CASE工具从80年代开始出现,但是早期的工具大多只是捕获所绘制图形的像素。尽管这些工具在商业上取得了一定的成功,但实际上并没有太大帮助。一个关键的见解是,如果附加的“设计”工件无法正式解释,那么您将无法获得任何认真的工具帮助。我认为,同样的见解适用于任何长期有用的设计捕获形式:如果没有正式的结构,它将不会有任何实际用途。文本文档几乎无法通过此测试。

10
在大型会议中如何有效地“销售”好的设计
我多次目睹悲惨的悲剧。这是发生了什么: 新项目的团队设计审查。 我看到一个简单的设计,其中有很多孔。 我随便提一下漏洞和避免漏洞的方法。 这些警告被诸如“在现实生活中从未发生过”之类的评论所忽略。 最终“永远不会发生”的事情发生了 紧急团队对已损坏项目的设计审查。 那我该怎么办?保持“我告诉过你”的态度不会赢得朋友和影响人。有时候,岁月流逝,而第3步中的评论却被遗忘了。我绝对不想成为让世界想起麻烦的烦人的害虫。我经常坐下来,看着泰坦尼克号驶向欧洲。 看到糟糕的设计前进很令人沮丧。同样令人沮丧的是,我似乎无法说服其他人当前路径的未决危险。我在团队会议上做得很差,每个人都有不同的理解不同术语的方式。同样,自负倾向于赢得理性和思想。我正在寻找能够说服小组成员使用一些新的复杂想法的好的策略。
14 design  team 

4
没有明显抽象的代码重复
您是否曾经遇到过代码重复的案例,在这种情况下,在查看代码行时,您无法对其进行专题描述以忠实地描述其在逻辑中的作用?您做了什么处理呢? 这是代码重复,因此理想情况下,我们需要进行一些折光处理,例如使其具有自己的功能。但是由于代码没有一个很好的抽象来描述它,所以结果将是一个奇怪的函数,我们甚至无法为其找到一个好名字,而且从逻辑上看,它在逻辑中的作用并不明显。对我来说,这损害了代码的清晰度。我们可以保留清晰度并保持原样,但随后会损害可维护性。 您认为解决此类问题的最佳方法是什么?

3
通过DRY和OOD引入代码耦合
我正在寻找有关DRY与代码耦合的指南。我不喜欢复制代码,也不喜欢无关模块之间的代码耦合。因此,如果在引入重复项一年后发现完全相同的重复代码,我将重构重复代码。但是,我越来越多地体验到现实世界中更加难以预测的情况,并且在重构代码之后,出现了一些情况,需要再次分叉代码。 例如,如果我有处理汽油车,汽油SUV,电动汽车和电动SUV的代码,可以说我将重复的代码重构为“汽油”层次结构和“电动”层次结构,它们均从“车辆”层次结构中衍生而来。到目前为止,一切都很好。然后,我的公司推出了混合动力汽车和混合动力汽车Semi-需要对我的原始等级本身进行核心更改。可能需要在汽油和电气层次之间进行“组合”。 显然,代码重复是不好的,因为它增加了实现上述所有产品共有的更改所花费的时间。但是重构通用代码使引入产品特定的变体同样困难,并且当人们不得不找到代码行来修复错误时,会导致很多“类跳转”-上级父类中的一项更改可以触发所有后代之间的回归错误。 如何在DRY与有害代码耦合之间达到最佳平衡?
14 design  dry  coupling 

3
允许不同版本的软件之间的文件向后兼容的最佳设计是什么?
有什么好的设计可以允许文件类型在不同版本的软件之间向后兼容? 例如,Microsoft如何将Word 2007、2010和2013等信息获取到所有打开的docx文件,但是不同版本可以保存更多/更少的数据,并以略有不同的方式保存数据,所有数据都保存到相同的文件类型,并且保存在一个版本中的文件可以在另一个版本中打开,但是文件的某些元素可能在较早版本中不可用? 我的意思是,最明显的方法是 private string openfile(string filename) { File.Open(filename) ... some logic that gets a header from the file that will never change switch (fileversion) case 2007: ..... case 2010 ..... case 2013 ..... } 但这似乎是令人难以置信的整体,不是很可扩展,并且可能导致大量复制/粘贴代码。 因此,我正在考虑对所有版本使用基本接口,该接口定义文件中需要存在的不变结构(例如标头)和需要用于序列化/反序列化的方法,然后进行多次继承,以便每个实现该接口的新版本的类继承了旧版本,并且仅覆盖已更改的内容,因为该文件在大多数情况下都是相同的。 我并没有真正为文件的结构而烦恼,因为它已经决定我们将使用XML,并且基本上已经确定了初始模式。但是,毫无疑问,将来会对其进行更改,我只希望能够以一种易于适应这些更改的方式来设计代码。

3
DAO应该是单身吗?
我正在开发RESTful API,我认为为我的资源使用DAO会很方便,因为尽管我计划仅使用内存来存储它们,但是我不想对使用库的任何人敞开大门,如果他们决定使用DAO的数据库实现。 我的问题是DAO是否应为单例。如果不是,则该服务将具有DAO的实例,并且看起来大致如下: @Path("eventscheduler") public class EventSchedulerService { private IEventSchedulerDao dao = new EventSchedulerDao(); // in case a different implementation is to be used public void setEventSchedulerDao(IEventSchedulerDao dao) { this.dao = dao; } @Path("{uniqueName}") @GET @Produces(MediaType.APPLICATION_JSON) public Tournament getTournament(@PathParam("name") String uniqueName) { return dao.get(uniqueName); } @Path("create") @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public …


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.