Questions tagged «design-patterns»

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

6
从下面的代码片段中跳过太多if / else-if的更好方法是什么?
我正在尝试编写一个servlet,它根据传递给它的“操作”值执行任务。 这是其中的示例 public class SampleClass extends HttpServlet { public static void action1() throws Exception{ //Do some actions } public static void action2() throws Exception{ //Do some actions } //And goes on till action9 public void doPost(HttpServletRequest req, HttpServletResponse res)throws ServletException, IOException { String action = req.getParameter("action"); /** * I find …

5
根据得墨'耳(Demeter)的法律,是否允许某类返回其成员之一?
关于德米特定律,我有三个问题。 除了专门指定用于返回对象的类(例如工厂类和构建器类)之外,还可以使用一种方法来返回对象,例如,由该类的一个属性持有的对象,或者会违反demeter(1)的定律。?并且,如果它违反了demeter的定律,那么返回的对象是否是一个不可变的对象(表示一个数据,并且除了该数据的吸气剂之外就什么也不包含)(2a),这会很重要吗?还是这样的ValueObject本身就是反模式,因为使用该类中的数据完成的所有操作都是在类(2b)之外完成的? 用伪代码: class A {} class B { private A a; public A getA() { return this.a; } } class C { private B b; private X x; public void main() { // Is it okay for B.getA to exist? A a = this.b.getA(); a.doSomething(); x.doSomethingElse(a); } } 我怀疑得墨meter耳的定律禁止这种模式。我该怎么做才能确保doSomethingElse()在不违反法律的情况下可以被调用(3)?

2
如何测试不可注入的代码?
因此,我在系统中使用了以下代码。目前,我们正在回顾性地编写单元测试(比我的观点迟来的要好得多),但是我不知道这将是可测试的吗? public function validate($value, Constraint $constraint) { $searchEntity = EmailAlertToSearchAdapter::adapt($value); $queryBuilder = SearcherFactory::getSearchDirector($searchEntity->getKeywords()); $adapter = new SearchEntityToQueryAdapter($queryBuilder, $searchEntity); $query = $adapter->setupBuilder()->build(); $totalCount = $this->advertType->count($query); if ($totalCount >= self::MAXIMUM_MATCHING_ADS) { $this->context->addViolation( $constraint->message ); } } 从概念上讲,这应该适用于任何语言,但是我正在使用PHP。该代码只是基于一个对象构建了一个ElasticSearch查询对象,而该Search对象又是从一个EmailAlert对象构建的。这些Search和EmailAlert只是POPO。 我的问题是,我不知道怎样才能模拟出的SearcherFactory(使用静态方法),也不是SearchEntityToQueryAdapter,它需要从结果SearcherFactory::getSearchDirector 和的Search实例。如何在方法中注入从结果中构建的内容?也许有一些我不知道的设计模式? 谢谢你的帮助!

1
数据库中的领域模型可以成为可持续的解决方案吗?
我刚开始担任新职位,是一家基于Microsoft技术的中小型公司的数据库开发人员。我很早就注意到关于最佳实践,设计模式,测试和项目管理的实践与我在学校所教的有多少不同。 最让我烦恼的是我们的主要数据库开发人员(以下称“约翰”)如何将模型架构保留在数据库中!为此,我们有3个“魔术”表;一种用于数据库方案,一种用于表,一种用于列。 将记录插入“ 表 ”表中(通过数据库触发器)会生成实际的对应表。在“ 行 ”表中插入一行会用该行更新引用的表。反过来,他的自制C#程序会读取这些代码以生成C#模型,前端开发人员将其用于控制​​器和外部。 除此之外,大多数开发都是根据ASP.NET MVC框架完成的。 我发现这种方法存在一些缺陷: 我们需要他维护ORM,而他很少有时间这样做(工作安全性很好!) “表”和“行”表的触发器存在缺陷。它们不支持表更新,也不支持检查约束或更多“高级”功能。虽然我们可以肯定地改进它们,但我不确定这是否可行。 将程序逻辑保存在数据库中感觉很奇怪且很严格(尽管可以通过C#扩展他的模型)。 他的C#模型生成器必须由3个人之一(我是其中之一)手动运行,并且还不成熟,无法包含在自动化构建过程中。 一些人建议逐步使用像Entity Framework这样的经过测试的真实产品,但他不予理,,并声称将业务逻辑保留在代码层中仅适用于小型应用程序和启动项目。 这篇文章导致了一些看起来像是经过深思熟虑的讨论,但这并不是我的意图。我只想对我们的体系结构方法进行一些说明。 将域模型保留在数据库中是否可以成为成长中的公司的可持续解决方案?

3
在某些情况下如何引起程序员的注意?
让我们从一个例子开始。 比方说,我有一个称为方法export,该方法在很大程度上取决于数据库架构。“严重依赖”是指我知道(经常)向特定表中添加新列会导致相应的export方法更改(通常也应将新字段也添加到导出数据中)。 程序员通常会忘记更改export方法,因为还不清楚您是否应该看一下。我的目标是迫使程序员明确决定是否要忘记查看该export方法还是只是不想在导出数据中添加字段。我正在寻找针对此问题的设计解决方案。 我有两个想法,但它们都有缺陷。 智能的“阅读所有”包装 我可以创建智能包装器,以确保显式读取所有数据。 像这样: def export(): checker = AllReadChecker.new(table_row) name = checker.get('name') surname = checker.get('surname') checker.ignore('age') # explicitly ignore the "age" field result = [name, surname] # or whatever checker.check_now() # check all is read return result 因此,checker断言if是否table_row包含另一个未读取的字段。但是,所有这些东西看起来有点沉重,并且(可能)会影响性能。 “检查该方法”单元测试 我可以创建一个能够记住最后一个表模式的单元测试,并且每次更改表时都会失败。在那种情况下,程序员会看到类似“不要忘了检查export方法”的信息。要隐藏警告程序员,可以(或不会-这是一个问题)签出export并手动(这是另一个问题)通过在其中添加新字段来修复测试。 我还有其他一些想法,但是它们太难实现或难以理解(我不希望该项目成为难题)。 上面的问题只是我不时遇到的更多问题的一个示例。我想绑定一些代码和/或基础结构,因此更改其中的一个代码会立即提醒程序员检查另一个代码和/或基础结构。通常,您有一些简单的工具,例如提取通用逻辑或编写可靠的单元测试,但是我正在寻找更复杂情况的工具:也许我现在知道一些设计模式。

7
是否有一种模式可以更自然地向收藏夹添加项目?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 5年前关闭。 我认为向集合中添加某些内容的最常见方法是使用Add集合提供的某种方法: class Item {} var items = new List<Item>(); items.Add(new Item()); 实际上,这没有什么不寻常的。 我不知道为什么我们不这样做: var item = new Item(); item.AddTo(items); 它似乎比第一种方法更自然。当Item类具有类似Parent以下属性时,将具有andvantange : class Item { public object Parent { get; private set; } } 您可以将二传手设为私人。在这种情况下,您当然不能使用扩展方法。 但是也许我错了,我以前从未见过这种模式,因为它是如此罕见?你知道有没有这种模式? 在C#扩展方法中将对此有用 public static T AddTo(this T item, IList<T> list) { list.Add(item); return …

6
质疑依赖关系注入框架的论点之一:为什么创建对象图很难?
像Google Guice这样的依赖注入框架为其使用(来源)提供了以下动机: 要构造一个对象,首先要建立它的依赖关系。但是要构建每个依赖项,您需要其依赖项,依此类推。因此,在构建对象时,确实需要构建对象图。 手工构建对象图是劳动密集型(...),并且使测试变得困难。 但是我不赞成这种观点:即使没有依赖注入框架,我也可以编写易于实例化且易于测试的类。例如,Guice动机页面中的示例可以用以下方式重写: class BillingService { private final CreditCardProcessor processor; private final TransactionLog transactionLog; // constructor for tests, taking all collaborators as parameters BillingService(CreditCardProcessor processor, TransactionLog transactionLog) { this.processor = processor; this.transactionLog = transactionLog; } // constructor for production, calling the (productive) constructors of the collaborators public BillingService() …

2
我应该将“计算”值公开为属性还是方法?
我有一个C#类,它表示Web内容管理系统中的内容类型。 我们有一个字段,允许Web内容编辑器输入HTML模板以显示对象的显示方式。它基本上使用把手语法将对象属性值替换为HTML字符串: <h1>{{Title}}</h1><p>{{Message}}</p> 从类设计的角度来看,我应该将格式化的HTML字符串(带有替换)作为属性或方法公开吗? 作为属性的示例: public class Example { private string _template; public string Title { get; set; } public string Message { get; set; } public string Html { get { return this.ToHtml(); } protected set { } } public Example(Content content) { this.Title = content.GetValue("title") as string; this.Message …

2
为什么用Handle()分隔类CommandHandler而不是Command本身的处理方法
我有一部分使用S#arp Architecture实施的CQRS模式,如下所示: public class MyCommand { public CustomerId { get; set; } // some other fields } public class MyCommandHandler<MyCommand> : ICommandHandler<MyCommand, CommandResult> { Handle(MyCommand command) { // some code for saving Customer entity return CommandResult.Success; } } 我想知道为什么不只Command包含数据和处理方法的类?这是一种可测试性的好处,您需要与命令属性分开测试命令处理逻辑吗?还是某些频繁的业务需求,您需要由不同的实现来处理一个命令ICommandHandler<MyCommand, CommandResult>?

4
Rails:德米特混乱法则
我正在阅读一本名为《 Rails反模式》的书,他们谈论使用委派来避免违反Demeter法则。这是他们的主要例子: 他们认为在控制器中调用这样的命令是不好的(我同意) @street = @invoice.customer.address.street 他们提出的解决方案是执行以下操作: class Customer has_one :address belongs_to :invoice def street address.street end end class Invoice has_one :customer def customer_street customer.street end end @street = @invoice.customer_street 他们说,由于您仅使用一个点,因此您没有违反Demeter定律。我认为这是不正确的,因为您仍在通过客户通过地址来获取发票的街道。我主要是从我读过的博客文章中得到这个想法的: http://www.dan-manges.com/blog/37 在博客文章中,主要的例子是 class Wallet attr_accessor :cash end class Customer has_one :wallet # attribute delegation def cash @wallet.cash end end …


3
使用单元测试讲故事是个好主意吗?
因此,我有一段时间前编写的身份验证模块。现在,我看到了自己的错误并为此编写了单元测试。在编写单元测试时,我很难想出好名字和好地方进行测试。例如,我有类似的东西 需要Login_should_redirect_when_not_logged_in 需要登录时登录_通过_登录_登录 Login_should_work_when_given_proper_credentials 就个人而言,即使看起来“适当”,我还是觉得它有点丑陋。我也难以通过仅扫描测试来区分测试(我必须至少读取两次方法名称才能知道失败了)。 因此,我认为也许不编写纯粹测试功能的测试,而是编写一组涵盖场景的测试。 例如,这是我想出的一个测试存根: public class Authentication_Bill { public void Bill_has_no_account() { //assert username "bill" not in UserStore } public void Bill_attempts_to_post_comment_but_is_redirected_to_login() { //Calls RequiredLogin and should redirect to login page } public void Bill_creates_account() { //pretend the login page doubled as registration and he made an …

2
是否有通常用于创建大型功能编程应用程序的特定工作流程或设计模式?[关闭]
已关闭。这个问题需要更加集中。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅通过编辑此帖子来关注一个问题。 4年前关闭。 我已经探索Clojure已有一段时间了,尽管我没有在任何重要的项目中使用过它。基本上,我对语法和某些惯用法已经很熟悉了。来自OOP的背景,Clojure是我非常关注的第一种功能语言,我自然对功能处理方式不太满意。 也就是说,创建大型功能应用程序时是否存在特定的工作流程或设计模式?我真的很想开始“真正地”使用函数式编程,但是由于我目前的专业知识不足,恐怕会导致史诗般的失败。 “四人帮”是面向OO程序员的标准,但是是否有类似的东西更针对功能范例呢?我发现的大多数资源都具有出色的编程能力,但它们并没有退缩以提供更广泛,更体系结构的外观。

4
如何确定设计模式是否正确实施?
我可以成功扩展所有未使用记录的设计模式的旧应用程序。我不知道是什么模式。在很大程度上,我只觉得需要使用简单的OOP概念。 设计模式的概念很复杂,很难理解。在实施时,如何确定实施是否正确以及应用程序是否具有真正的松散耦合?

3
推荐一种设计模式/方法来暴露/容忍/从系统错误中恢复,异常处理(例如Java,C ++,Perl,PHP)
您能推荐一种设计模式/方法来暴露/容忍/从系统错误中恢复,异常处理(Java,C ++,Perl,PHP)吗? 一些错误需要报告。 某些错误可以在内部处理(通过重试或不重要的处理(可以忽略))。 您如何构造代码以捕获它们? 但是所有错误都需要记录。 有哪些最佳实践? 为了模拟它们能够完全测试受它们影响的组件? 适用于几种现代编程语言的一般非编程语言特定问题,但将欢迎使用Java,C ++,PHP和Perl进行模式,方法和哲学的示例说明。 (也在stackoverflow中问过:https : //stackoverflow.com/questions/7432596/recommend-a-design-pattern-approach-to-exposed-tolerating-recovering-from-system, 但我认为也应该在程序员中提出,因为我认为程序员的问答涵盖了更广泛的软件/编程问题,而stackoverflow则更多地是关于技术实现(IMHO)。

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.