Questions tagged «design-patterns»

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

2
如何通过依赖项注入管理配置?
我是DI / IOC的忠实粉丝。它非常适合处理/抽象出硬依赖关系,并使生活更轻松。 但是,我对此有些疑惑,我不确定该如何解决。 DI / IOC的基本思想是,当实例化对象时,其所有依赖项都将在构造函数中预先填充。 但是恕我直言,构造函数有几种类型的参数(尤其是当您的对象是不可变的时)。 依赖关系(您的对象正常工作所需的对象) 配置(有关工作所需环境的信息) 参数(完成工作的数据) 我发现IOC可以很好地处理依赖关系。但我仍在尝试找出与其他两个人打交道的最佳方法。但是,由于构造函数是要由IOC容器运行的,因此似乎需要将这些项目放入IOC容器中。 我想知道人们采用什么策略/模式,人们发现了哪些优点和缺点。 注意 我知道这是一个高度主观的问题,并且根据SE指南已尝试将其设为“好”主观问题。

3
如何设计网站工作流程?
我已经思考了很长时间,却没有找到最佳答案。 首先,我是一位热爱编程的医生,但从未真正地学习过它,除了在家学习和在业余时间玩代码很多年之外。 目前,我正在尝试建立一个小型项目来管理我的诊所,为此,我首先创建了一个我希望能够做的选择列表。 例: 活跃的患者记录。 具有不同角色(例如,患者,护士,博士)的身份验证 预约时间表(包括日历,定期接种疫苗/手术等,并带有提醒) 允许医生创建自己的插件。 仪表板,供医生查看其统计信息 然后,我开始使用codeigniter / mysql / php / jquery并开始编码。 我在开发过程中的步骤:- 第一个数据库。 首先创建所有需要的表。 创建了我所有的模型来处理这些表(1个主模型,在处理基本读/写/更新/验证的同时还考虑了我的表关系 之后,我开始为视图和控制器编码。我首先创建了视图HTML,然后创建了将处理该视图的控制器,并开始编写函数以使视图交互有效。 编写约会视图时的示例(控制器booking.php): 当用户单击时,创建此布局并使表td可单击:jquery get(booking / add_ Patient_form)并弹出它 用户保存时:发布到预订/保存-保存约会,然后重新加载index()函数 等。我继续执行创建视图的相同步骤,然后创建其控制器-包含该视图所需的所有逻辑-完成整个项目。 最后,我所有的目标功能都运行良好,但是由于从一开始就没有PLAN,而且由于整个项目都是脑力激荡和调试,没有任何计划,所以在完成该项目后,我发现自我维护性和灵活性!并且无法将它们链接在一起。 我感觉到网站上的每个页面都是彼此完全隔离的,我什至不记得每个页面的加载方式和内部的功能,而不会偷看! 无论如何,我可以恢复它并进行设计吗?


3
关于装饰器设计模式的新手问题
我在阅读编程文章,其中提到了装饰器模式。我已经进行了一段时间编程,但没有进行任何形式的教育或培训,但是我正在尝试学习标准模式等。 因此,我抬起头来查看装饰器,并在上面找到了维基百科的文章。我现在了解了装饰器模式的概念,但是我对这段内容感到有些困惑: 例如,考虑一个窗口系统中的一个窗口。为了允许滚动窗口的内容,我们可能希望适当地向其添加水平或垂直滚动​​条。假定窗口由Window类的实例表示,并且假定此类不具有添加滚动条的功能。我们可以创建一个提供它们的子类ScrollingWindow,也可以创建一个ScrollingWindowDecorator将此功能添加到现有的Window对象中。此时,任何一种解决方案都可以。 现在假设我们也希望能够向窗口添加边框。同样,我们原始的Window类不支持。ScrollingWindow子类现在带来了一个问题,因为它有效地创建了一种新型的窗口。如果希望对所有窗口添加边框支持,则必须创建子类WindowWithBorder和ScrollingWindowWithBorder。显然,随着每个新功能的添加,此问题变得更加严重。对于装饰器解决方案,我们只需创建一个新的BorderedWindowDecorator,在运行时,我们可以根据需要使用ScrollingWindowDecorator或BorderedWindowDecorator或两者来装饰现有窗口。 好的,当他们说要向所有窗口添加边框时,为什么不只是在原始Window类中添加功能以允许该选项呢?我所看到的方式是,子类化仅是为类添加特定功能或重写类方法。如果需要向所有现有对象添加功能,为什么不修改超类来这样做呢? 文章中还有另一行: 装饰器模式是子类的替代方法。子类化在编译时增加了行为,并且更改会影响原始类的所有实例;装饰可以在运行时为单个对象提供新的行为。 我不明白他们说“ ...更改影响原始类的所有实例”的原因-子类化如何更改父类?这不是继承的全部重点吗? 我将假设该文章像许多Wiki一样,书写不清晰。我可以在最后一行看到装饰器的用处-“ ...在运行时为单个对象提供新的行为。” 如果不了解这种模式,那么如果我需要在运行时更改单个对象的行为,则可能会在超类或子类中构建一些方法来启用/禁用所述行为。请帮助我真正了解装饰器的用途,为什么我的新手思维有缺陷?

5
为什么MVC比PAC更受欢迎?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 4年前关闭。 我刚在SO上偶然发现一个有关PAC的问题,并对这种模式感兴趣。我想知道为什么它不像MVC那样广泛使用?与PAC相比,MVC有什么好处?

1
什么是灌注泵?有时称为预读
过去,我已经学会了这种表达方式和模式。当然,这个名字来自于那些老式泵,在泵水之前必须先注满水,但是谁在乎呢?我们在这里谈论代码。 我们将欢迎您提供一些非常好的示例,并对模式的完成情况进行解释。今天如何看待这种模式? 灌注有时会导致有缺陷的循环工作,但要付出DRY的代价。因此,这可能是短暂停止更好设计的途中。这被认为是反模式吗?有其他选择吗?

2
最小惊讶原理(POLA)和界面
25年前,当我学习C ++时,我被教导说接口应该是宽容的,并且尽可能不在乎方法的调用顺序,因为消费者可能无法访问源代码或文档来代替这个。 但是,每当我指导初级程序员和高级开发人员听到我的消息时,他们都会惊讶地做出反应,这让我怀疑这是否真的是一件事情,或者它是否已经过时了。 像泥一样清澈? 考虑具有以下方法的接口(用于创建数据文件): OpenFile SetHeaderString WriteDataLine SetTrailerString CloseFile 现在,您当然可以按顺序浏览这些文件,但是说您不关心文件名(认为a.out)或包括什么标题和尾部字符串,您可以致电AddDataLine。 一个不太极端的示例可能是省略标题和结尾。 还有一种可能是在打开文件之前设置标题和结尾字符串。 这是公认的接口设计原则,还是只是在命名之前采用POLA方式? 注意:不要被这个界面的细节所困扰,这仅仅是一个例子。

4
单一责任原则是否适用于职能?
根据Robert C. Martin所说,SRP指出: 改变班级的理由不应该只有一个以上。 但是,在他的《清洁代码》第3章:函数中,他显示了以下代码块: public Money calculatePay(Employee e) throws InvalidEmployeeType { switch (e.type) { case COMMISSIONED: return calculateCommissionedPay(e); case HOURLY: return calculateHourlyPay(e); case SALARIED: return calculateSalariedPay(e); default: throw new InvalidEmployeeType(e.type); } } 然后指出: 此功能有几个问题。首先,它很大,并且当添加新的雇员类型时,它会增长。其次,它显然做的不止一件事。第三,它违反了“单一责任原则”(SRP),因为有多个原因使其改变。[强调我的] 首先,我认为SRP是为类定义的,但事实证明它也适用于函数。其次,该功能有多个原因需要改变吗?我只能看到它随着Employee的变化而改变。

5
枚举会创建脆弱的接口吗?
考虑下面的示例。对ColorChoice枚举的任何更改都会影响所有IWindowColor子类。 枚举会导致界面脆弱吗?是否有比枚举更好的东西可以提供更多的多态灵活性? enum class ColorChoice { Blue = 0, Red = 1 }; class IWindowColor { public: ColorChoice getColor() const=0; void setColor( const ColorChoice value )=0; }; 编辑:很抱歉使用颜色作为我的示例,这不是问题所在。这是一个不同的示例,它避免出现红色鲱鱼,并提供有关灵活性的更多信息。 enum class CharacterType { orc = 0, elf = 1 }; class ISomethingThatNeedsToKnowWhatTypeOfCharacter { public: CharacterType getCharacterType() const; void setCharacterType( const CharacterType …

7
如果我不使用软件设计模式怎么办?[关闭]
已关闭。这个问题需要更加集中。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅通过编辑此帖子来关注一个问题。 6年前关闭。 如果不使用软件设计模式,我可能会遇到什么样的问题?您能告诉我使用标准的面向对象技术进行设计的问题吗?

8
在UnitTesting之外值得依赖注入吗
给定一个构造函数,它永远不必使用初始化它的几个对象的任何不同实现,使用DI仍然可行吗?毕竟,我们可能仍要进行单元测试。 有问题的类在其构造函数中初始化了其他一些类,并且使用的类非常特定。它永远不会使用其他实现。我们有理由避免尝试对接口进行编程吗?

3
国家模式是否违反《里斯科夫替代原则》?
该图像取自“ 应用域驱动的设计和模式:带有C#和.NET中的示例” 这是状态模式的类图,其中a SalesOrder在生命周期内可以具有不同的状态。在不同状态之间仅允许某些转换。 现在,OrderState该类是一个abstract类,并且其所有方法都继承为其子类。如果我们将子类视为Cancelled最终状态,不允许将其转换为其他任何状态,则必须对override此类中的所有方法进行抛出。 现在,这不是违反Liskov的替代原则吗,因为sublcass不应改变父级的行为吗?将抽象类更改为接口是否可以解决此问题? 如何解决?


2
储存库和工作单元之间的关系
我将实现一个存储库,并且我想使用UOW模式,因为该存储库的使用者可以执行多个操作,因此我想一次提交它们。 在阅读了有关该问题的几篇文章之后,我仍然不知道如何将这两个元素联系起来,具体取决于文章是通过其他方式完成的。 有时,UOW是存储库内部的内容: public class Repository { UnitOfWork _uow; public Repository() { _uow = IoC.Get<UnitOfWork>(); } public void Save(Entity e) { _uow.Track(e); } public void SubmittChanges() { SaveInStorage(_uow.GetChanges()); } } 有时它是外部的: public class Repository { public void Save(Entity e, UnitOfWork uow) { uow.Track(e); } public void SubmittChanges(UnitOfWork uow) { SaveInStorage(uow.GetChanges()); …

6
避免在Controllers中使用SQL的策略…或者我的模型中应该有多少种方法?
因此,我遇到的情况经常是我的模型开始出现以下情况之一: 用无数种方法成长为怪物 要么 允许您将SQL片段传递给它们,以便它们足够灵活,不需要一百万种不同的方法 例如,假设我们有一个“小部件”模型。我们从一些基本方法开始: get($ id) 插入($ record) 更新($ id,$ record) 删除($ id) getList()//获取小部件列表 一切都很好,但是然后我们需要一些报告: listCreatedBetween($ start_date,$ end_date) listPurchasedBetween($ start_date,$ end_date) listOfPending() 然后,报告开始变得复杂: listPendingCreatedBetween($ start_date,$ end_date) listForCustomer($ customer_id) listPendingCreatedBetweenForCustomer($ customer_id,$ start_date,$ end_date) 您可以看到增长的地方...最终,我们有如此多的特定查询要求,我要么需要实现大量的方法,要么可以将某种“查询”对象传递给单个-> query(query $ query)方法... ...或者只是硬着头皮,开始做这样的事情: list = MyModel-> query(“开始日期> X AND结束日期<Y AND待定= 1 AND customer_id = Z”) …

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.