Questions tagged «design»

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

4
将线程/后台工作者放在一类中是“错误的” /错误的设计吗?
我有一个可以从Excel中读取的类(C#和.Net 4),在该类中,我有一个后台工作程序,该工作程序将从Excel加载数据,同时UI可以保持响应。我的问题如下:在班级中有一名后台工作人员是不好的设计吗?我是否应该在没有该类的情况下创建我的课程,并使用后台工作者对该课程进行操作?我看不到以这种方式创建课程的任何问题,但是我还是新手,所以我认为在继续之前必须确定。 我希望这个问题在这里有意义,因为我认为在我的代码正常工作时,它不应该出现在stackoverflow上,这只是一个设计问题。

5
是否可以在不增加耦合的情况下应用DRY?
假设我们有一个实现功能F的软件模块A。另一个模块B实现了与F'相同的功能。 有多种方法可以消除重复的代码: 让A使用B的F'。 让B使用A中的F。 将F放入自己的模块C中,让A和B都使用它。 所有这些选项都会在模块之间生成其他依赖关系。他们以增加耦合为代价应用了DRY原理。 据我所知,在应用DRY时,耦合总是增加或至少增加到更高的水平。软件设计的两个最基本的原则之间似乎存在冲突。 (实际上,这样的冲突并不令人惊讶。这可能是使良好的软件设计如此困难的原因。我确实感到惊讶的是,通常在介绍性文本中未解决这些冲突。) 编辑(为澄清起见):我认为F和F'的相等不只是一个巧合。如果必须修改F,则很可能必须以相同的方式修改F'。

3
大量构建一种实现。DI无望吗?使用服务定位器?
假设我们有1001个客户端,它们直接构造其依赖关系,而不接受注入。根据我们的老板,重构1001不是一个选择。实际上,甚至不允许我们访问其源代码,而只能访问类文件。 我们应该做的是“现代化”这1001个客户所经历的系统。我们可以重构自己喜欢的一切。依赖关系是该系统的一部分。还有一些依赖关系我们应该更改为具有新的实现。 我们想要做的是能够配置依赖关系的不同实现,以满足众多客户的需求。可悲的是,DI似乎不是一个选择,因为客户端不接受构造函数或setter的注入。 选项: 1)重构客户端使用的服务的实现,以使其执行客户端现在需要的功能。砰,我们完成了。不灵活。不复杂。 2)重构实现,以便将其工作委托给它通过工厂获取的另一个依赖项。现在,我们可以通过重构工厂来控制它们都使用哪种实现。 3)重构实现,以便将其工作委托给它通过服务定位器获取的另一个依赖项。现在,我们可以通过配置服务定位器来控制它们都使用哪种实现,该服务定位器可能只是hashmap对象的字符串,并且需要进行一些强制转换。 4)我什至没有想到的东西。 目标: 在不增加毫无意义的复杂性的情况下,将因设计欠佳的旧客户端代码拖到将来而导致的设计损失最小化。 客户不应该了解或控制其依赖项的实现,但是他们坚持使用来构建它们new。我们无法控制,new但可以控制他们正在构建的类。 我的问题: 我没有考虑什么? Doc Brown的问题 您是否真的需要在不同的实现之间进行配置?出于什么目的? 敏捷。很多未知数。管理层希望变革的潜力。只失去对外界的依赖。还测试。 您是否需要运行时机制或只是编译时机制来在不同的实现之间进行切换?为什么? 编译时间机制可能就足够了。除测试外。 您需要在实现之间切换哪种粒度?一次全部?每个模块(每个模块包含一组类)?每堂课? 在1001中,任何一次都只能运行一次。一次更改所有客户端使用的内容可能很好。但是,对依赖项的单独控制可能很重要。 谁需要控制开关?只有您/您的开发人员团队?管理员?每个客户自己吗?还是客户的代码的维护开发人员?那么,机械师需要多么容易/稳健/万无一失? 开发测试。管理员随着外部硬件依赖性的变化而变化。它需要易于测试和配置。 我们的目标是证明该系统可以快速重建和现代化。 实施开关的实际用例? 一种是,在硬件解决方案准备就绪之前,一些数据将由软件提供。

5
OOP编码风格:初始化构造函数上的所有内容吗?
我仍然认为自己是一个学徒程序员,所以我一直在寻找学习典型编程的“更好”方法。今天,我的同事认为我的编码风格做了一些不必要的工作,我想听听别人的意见。通常,当我使用OOP语言(通常是C ++或Python)设计类时,会将初始化分为两个不同的部分: class MyClass1 { public: Myclass1(type1 arg1, type2 arg2, type3 arg3); initMyClass1(); private: type1 param1; type2 param2; type3 param3; type4 anotherParam1; }; // Only the direct assignments from the input arguments are done in the constructor MyClass1::myClass1(type1 arg1, type2 arg2, type3 arg3) : param1(arg1) , param2(arg2) , param3(arg3) {} …

1
相互实现两个Java 8默认方法是否是一种好习惯?
我正在设计一个具有两个相关方法的接口,类似于此方法: public interface ThingComputer { default Thing computeFirstThing() { return computeAllThings().get(0); } default List<Thing> computeAllThings() { return ImmutableList.of(computeFirstThing()); } } 大约一半的实现只会计算一件事,而另一半可能会计算更多。 这在广泛使用的Java 8代码中是否有先例?我知道Haskell在某些类型类中做类似的事情(Eq例如)。 好处是,与拥有两个抽象类(SingleThingComputer和MultipleThingComputer)相比,我必须编写更少的代码。 不利的一面是,一个空的实现可以编译,但是在运行时会用炸掉StackOverflowError。可以使用a来检测相互递归ThreadLocal并给出更好的错误,但这会增加非Buggy代码的开销。

3
在实践中如何遵守开闭原则
我了解开放原则的意图。这是通过告诉您尝试在不进行修改的情况下进行扩展,以降低破坏已在修改过程中起作用的内容的风险。 但是,我在理解此原理在实践中的应用时遇到了一些麻烦。据我了解,有两种方法可以应用它。在可能的更改之前和之后: 之前:编程抽象并尽可能“预测未来”。例如,drive(Car car)如果将来将Motorcycles添加到系统中,则必须更改 方法,因此它可能违反了OCP。但是该方法drive(MotorVehicle vehicle)将来不太可能需要更改,因此它遵循OCP。 但是,很难预测未来并提前知道将对系统进行哪些更改。 之后:需要更改时,扩展类而不是修改其当前代码。 练习1并不难理解。但是,在实践2中,我很难理解如何申请。 例如(我从YouTube视频中获取了它):假设我们在类中有一个接受CreditCard对象的方法:makePayment(CraditCard card)。将一天Voucher添加到系统中。此方法不支持它们,因此必须对其进行修改。 首先实现该方法时,我们无法预测未来,无法以更抽象的术语进行编程(例如makePayment(Payment pay),因此现在我们必须更改现有代码。 练习2说,我们应该通过扩展而不是修改来添加功能。这意味着什么?我应该继承现有的类而不是简单地更改现有的代码吗?我是否应该围绕它进行某种包装,以避免重写代码? 还是该原则甚至不涉及“如何正确修改/添加功能”,而是涉及“如何避免必须首先进行更改(即从程序到抽象)”?

8
编码前的概念和设计:这是多少?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 5年前关闭。 我在学校和其他地方都学到,良好的开发方法在正确编码之前需要概念和设计。 即使对于初学者,这也不是一个新信息。但是,我想知道这是否是一个好的建议,因为自从我开始使用多种编程语言进行开发以来,自从开始以来就从未成功设计和构思过所有东西。 我的意思是,我总是融合设计,概念和编程。我是世界上最糟糕的开发人员,还是我们在学校学到的想法只是一种古老而毫无意义的宗教教条? 我们如何甚至可以构思和设计以前从未经历和编程的东西?是不是很荒谬?编程不是主导概念和设计吗?

5
我应该在实现之前编写接口API吗?
最近,我一直在研究更多的“有组织的”编程,并且我一直在学习应该对接口而不是对实现进行编程。考虑到这一点,在可能的情况下为项目编写实现之前,最好在接口中“略过”项目吗? 如果是这种情况,那么在使用第三方库(即Lidgren)的情况下,我是否也应该将它们包装在接口中并通过IOC容器进行解析,还是可以将它们公开给接口?

2
设计决策-为什么不生成</ p>的<p>?
tl; dr 假设浏览器将正确关闭段落,则一些生成html的广泛使用的程序将仅生成开始段落标签,而不会生成关闭段落标签。 从表面上看,在我看来,浏览器将正确关闭段落的假设是不正确的。我的解释正确吗?更笼统地说,这种决策涉及哪些权衡? 浏览moinmoin源代码时,以下代码行引起了我的注意: # We only open those tags and let the browser auto-close them: _auto_closing_tags = set(['p']) (来源) 在阅读完其余的实现后,我已经使自己确信,是的,的确,当moinmoin为其中一个页面生成html代码时,它将在适当的情况下正确生成段落打开标签,同时有目的地避免任何段落关闭标签(尽管能够做到这一点)。 对于我特定的,相当不寻常的用例,这种行为是不正确的。我很想提交错误报告和/或更改行为。但是,看起来这个设计决定是经过深思熟虑的。我不太熟悉html标准或各种浏览器实现的复杂性,因此无法总体上判断这是否是正确的行为,而且我感觉我本能的纠正/更改此行为的本能可能是被误导了。 这段代码是否对浏览器的实现做出了正确的假设?生成的html有效吗?更一般而言,我可能会在这里失去哪些权衡?

10
为什么RDBMS不以嵌套格式返回联接的表?
例如,假设我要获取一个用户及其所有电话号码和电子邮件地址。电话号码和电子邮件存储在单独的表中,多个电话/电子邮件的一位用户。我可以很容易地做到这一点: SELECT * FROM users user LEFT JOIN emails email ON email.user_id=user.id LEFT JOIN phones phone ON phone.user_id=user.id 问题在于,它会为每条记录(用户通过电子邮件发送电话记录)一遍又一遍地返回用户名,DOB,最喜欢的颜色以及存储在用户表中的所有其他信息,这可能会占用带宽并减慢速度降低结果。 那岂不是更好,如果它返回一个单列为每个用户,而该纪录内有一个列表的电子邮件和列表的手机?这也将使数据更容易使用。 我知道您可以使用LINQ或其他框架来获得类似的结果,但这似乎是关系数据库的基础设计中的一个弱点。 我们可以通过使用NoSQL解决此问题,但是不应该有一些中间立场吗? 我想念什么吗?为什么不存在? *是的,它是按照这种方式设计的。我知道了。我想知道为什么没有替代方法更容易使用。SQL可以继续做它在做的事情,但是他们可以添加一个或两个关键字来做一些后期处理,这些后处理以嵌套格式而不是笛卡尔乘积返回数据。 我知道可以使用您选择的脚本语言来完成此操作,但是它要求SQL Server发送冗余数据(下面的示例),或者发出多个查询,例如SELECT email FROM emails WHERE user_id IN (/* result of first query */)。 而不是让MySQL返回类似于此的内容: [ { "name": "John Smith", "dob": "1945-05-13", "fav_color": "red", "email": "johnsmith45@gmail.com", …
14 design  sql  rdbms 

7
代理密钥是否应该向用户公开?
通常,在没有自然键的表中,对于用户来说,拥有唯一生成的标识符仍然很有用。如果表具有代理主键(在这种情况下,您一定会希望它具有),该键应该向用户公开还是应将另一个字段用于该目的? 不公开代理键的原因之一是,现在您不能执行保留记录之间关系的操作,而只能更改键值,例如某些类型的删除/重新插入,将数据从一个数据库复制到数据库的许多方法。另一个等等 公开代理键的主要优点是使用您拥有的字段非常简单。 在什么情况下最好直接向用户公开代理密钥?

3
使用策略模式的Java通用文件解析器设计
我正在开发一种产品,其中一个模块的职责是解析XML文件并将所需内容转储到数据库中。即使目前的要求只是解析XML文件,我仍希望以一种将来可以支持任何类型文件的方式设计解析模块。采用这种方法的原因是,我们正在为特定客户生产该产品,但计划在不久的将来将其出售给其他客户。当前客户端的生态系统中的所有系统都会生成和使用XML文件,但其他客户端可能并非如此。 到目前为止,我尝试了什么?(现在) 我想到的是基于策略模式的以下设计。我很快就用eclipse编写了代码以传达我的设计,因此,如果暂时忽略其他方面(如正确的异常处理方式),那将是很好的选择。 Parser:公开解析方法的策略接口。 public interface Parser&lt;T&gt; { public T parse(String inputFile); } *使用泛型参数的原因是允许任何返回类型以及在编译时确保类型安全。 ProductDataXmlParser一个具体类,用于解析包含产品相关信息的product.xml文件。(使用XMLBeans) public class ProductDataXmlParser implements Parser&lt;ProductDataTYPE&gt; { public ProductDataTYPE parse(String inputFile) { ProductDataTYPE productDataDoc = null; File inputXMLFile = new File(inputFile); try { productDataDoc = ProductDataDocument.Factory.parse(inputXMLFile); } catch(XmlException e) { System.out.println("XmlException while parsing file : "+inputXMLFile); …
14 java  design  parsing  xml 

1
我们使用存储库模式正确吗?
我们正在使用一堆带有后缀的独立类,-repository以从数据库中检索数据。每个表都有自己的存储库。 例如,我们有一个customerrepository具有各种方法来检索客户的类,并且具有一个vacancyrepository具有各种方法来检索空缺的类。 关于这种做事方式,我有两个问题: 如何获取跨越多个表的数据?例如,我有一个屏幕,显示所有尚未创建空缺的客户。可以customerrepository从中使用方法vacancyrespository,还是两个存储库都返回结果,并且层次结构中是否有更高的类(我们将其命名为a dataservice)从两个存储库中获取结果并将它们合并为1个结果? 这样的存储库可以处理多少逻辑? 我认为可以在存储库中实现“ where active == true”以仅检索活动记录,还是应该由层次结构中较高的类来处理简单的逻辑(将其命名为a dataservice)? 我现在遇到的示例是以下示例: 我们有一个问题列表,其中包含一个或多个问题。 问题可以有一个结果,该结果保存在单独的表中。 因此,当您要检索问题列表的总结果时,必须合并questionlist表,问题表和questionstatus表中的数据。 现在,我们为这些表提供3个不同的存储库。 如果我要问questionlistrepository清单12的总结果是什么,那将不得不从另外两个存储库中获取数据,因此其中有些逻辑,这是允许的吗? 还是有questionlistdataservice哪个知道要使用哪个存储库? 还有一件事:我们的存储库可以生成一个结果,IQueryable以便调用服务可以轻松地合并结果,但是如果不是这种情况,我认为从列表中检索所有三个表的所有内容不是一个好主意。数据库。

8
技术面试中与OO设计相关的问题[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 4年前关闭。 我最近参加了很多访谈,并且公司要求他们多次回答“设计[插入模型]”问题。 如今,这在行业中很正常吗?我进入软件界已有二十多年了,参加了我的部分采访,但是我看到这种采访模式只是在最近才出现。 我觉得这个问题很开放。例如:我被要求绘制一个类图以“设计停车场”。我不确定面试官期望的详细程度。这是在网上测试中,我应该附上一个visio图,所以我不能问他们对他们的期望是什么。 您是否在面试过程中使用了这类问题?它们仅与类图相关,还是您还询问顺序,流程图和ERD(当然取决于职位的性质),它们在招聘过程中是否有效? *编辑凯文的回应* 例如:一个完整​​的问题可能是“设计可用于查找空位的停车场管理系统” 我可以用2班来完成,ParkingLot而Slot我也可以继续添加IVehicle和Vehicle及Car和Motorcycle类。我在哪里划界线? public class ParkingLot { IVehicle Vehicle {set; get;} List&lt;Slot&gt; GetEmptySlots() { }; } public class Vehicle : IVehicle { Slot SlotNum {set; get;} } public class Slot { int Row {set; get;} int Column {set; get; } }

5
是否有“实用”类值得关注?[关闭]
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案会得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意调查或扩展讨论。如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 7年前关闭。 我有时会创建“ Util”类,这些类主要用于保存似乎并不真正属于其他地方的方法和值。但是每次创建这些类之一时,我都会想:“哦,哦,我以后会后悔的……”,因为我在某处读到不好。 但另一方面,似乎有两个令人信服的案例(至少对我而言): 包中多个类中使用的实现机密 提供有用的功能来扩展类,而不会使其界面混乱 我要毁灭了吗?你说的话 !!我应该重构吗?

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.