Actual greedy algorithms are prone to suffering from converging to locally optimal solutions, while missing a globally optimal solution.
This holds true if EPIC technical User Story and guideline is not established, along with the normal business EPIC user story.
Has this been people's experience?
At times yes, it has been my experience. One instance was when the user stories we worked on were broken down too much, and the solution was to broaden them to get a more global outlook at our designs. And at times it was different enterprise scrum teams in the same projectt, conflicting with different technical framework uses and approaches.
Is it actually a problem?
It is only a problem, if you ignore the technical EPIC user story or guideline.
If so, what techniques do you use to avoid such local optima and yet remain agile?
Here is one Agile approach to solving this: During Agile Release planning, instead of just coming up with a Business EPIC User Story, also come up with a Technical EPIC User Story. The Technical EPIC User story would have the product vision from a technical stand point, in terms of technical architecture, application framework, quality standards, and global design considerations etc. These could be broken down into smaller technical user stories, and have a Scrum Team which works on getting those user stories working. An example of a user story could be: "As a Technical Project Manager, I want the whole enterprise project using A, B, C framework, and coding as per X,Y,Z coding standards, so that there is uniformity in project development work. If you don't want to form a scrum team separately for this, then just keep them as reminder cards next to backlogs for development teams to use as guidelines.
As a testing guideline, we used to have successful integration testing as a done criteria for each backlog. A global test was conducted in an integration environment, on all working software deployed from all enterprise teams, to deem it shippable. So right from inception to end of the backlog, the theme is set for global working software and not just local working software.
Finally, Agile development involves keeping a constant eye on quality, and one of the quality issues could be bad design or a too localized design. As and when this is discovered, it should be redesigned within that backlog itself, and followed going forward for other Backlogs.
I've been on a project which has had this problem, and has not dealt with it effectively.
The local quality of the code - over the scale of a package, say - was not bad. But there were problems at larger scales; things like duplication of logic (but not code) between packages, use of batch recomputation jobs where we should be using event-driven approaches, splitting the system into separate services at the wrong place, etc.
None of these problems could be fixed by refactoring a single class or package. As a result, they never happened in the normal course of events. We did refactorings at smaller scale - when adding a feature, we'd refactor in that area before starting, and again after we finished (as well as making some effort to write good code as we were going). But that never led to refactoring larger, architectural concerns.
We were all conscious of the problems, we just didn't have anything in our process that let us fix them.
One notable victory we did have was where there was duplication between two distantly related module. Essentially, there was code to render a web page showing the results of some set of calculations, and also a background job to generate reports doing similar calculations. The calculation code was shared, but the code to set up the calculations was not; one was driven by a user's view preferences, whereas the other was driven by a configured reporting job. We had a feature to implement that would have involved adding a new aspect to the calculations, which would have meant adding more items to both kinds of configuration, and then adding business logic to both sets of calculation setup code. We managed to get the product manager (our customer proxy) to agree to budget enough time for the work that we could refactor to unite the ideas of user view preferences and configured reporting job, so throwing away one of the sides of the duplication, then implement the feature. This took longer than just implementing it twice, but the product manager was wise enough to realise that this would let us implement future features spanning both pages and reports more quickly.
The mechanism in the process by which we did this was writing stories for the job of refactoring. Essentially, something like "As a product manager, i want pages and reports to use common calculation setup code, so that i can get features added more quickly". This is absolutely not a proper kind of story, but it fitted in the system, and it did the job.
I think that if the running of this project had been a bit healthier, then there would have been a steady stream of stories like this. We would acknowledge that we had a lot of architectural debt, and that work to pay it off had value, and allocate a fixed fraction of our time to it, perhaps about 20% (which would really mean one pair at a time). We could then have generated features/epics, stories, and tasks just as we did for customer-oriented work. These would originate from the team themself, rather than the product managers.
Sadly, there wasn't quite enough communication and trust between the development and product management sides that this was feasible; we could say to product that we had a problem, it was important, and that it would take so long to fix, and they couldn't know if that was true or not. As such, they were generally unwilling to schedule time to do it. The sad thing was that everyone was in agreement that there were problems and it would be good to fix them, we just had an impasse over actually doing it.
in my experirence, if you´re working a project context with fixed time/requirements then yes, most of the times Agile leads to local optima.
But my point is that in a complex endeavour, the requirements, the team itself and even the goals change. Agile is also about embracing changes. Then, paradoxically, this greedy strategy arrises as a reasonable option for global optimization when dealing with moving targets.
发布评论
评论(3)
如果 EPIC 技术用户故事和指南以及正常的业务 EPIC 用户故事没有建立,情况也是如此。
有时是的,这是我的经历。一个例子是,当我们处理的用户故事被分解得太多时,解决方案是扩大它们,以获得更全球化的设计视野。有时,同一项目中的不同企业 Scrum 团队会与不同的技术框架用途和方法发生冲突。
如果您忽略技术 EPIC 用户故事或指南,这只是一个问题。
这是解决这个问题的一种敏捷方法:
在敏捷发布规划期间,不仅要提出业务 EPIC 用户故事,还要提出技术 EPIC 用户故事。技术 EPIC 用户故事将从技术角度出发,在技术架构、应用程序框架、质量标准和全局设计考虑因素等方面具有产品愿景。这些可以分解为更小的技术用户故事,并有一个 Scrum 团队它致力于让这些用户故事发挥作用。用户故事的一个例子可以是:“作为技术项目经理,我希望整个企业项目使用 A、B、C 框架,并按照 X、Y、Z 编码标准进行编码,以便项目开发具有统一性工作。
如果您不想为此单独组建一个 Scrum 团队,那么只需将它们作为提醒卡放在积压工作旁边,供开发团队用作指导即可。
作为测试指南,我们曾经将成功的集成测试作为每个待办事项的完成标准。在集成环境中对所有企业团队部署的所有工作软件进行了全局测试,以确保其可以交付。因此,从积压工作的开始到结束,主题都是为全球工作软件而不仅仅是本地工作软件设定的。
最后,敏捷开发涉及对质量的持续关注,质量问题之一可能是糟糕的设计或过于本地化的设计。当发现这一点时,应该在该待办事项本身中重新设计它,并继续处理其他待办事项。
This holds true if EPIC technical User Story and guideline is not established, along with the normal business EPIC user story.
At times yes, it has been my experience. One instance was when the user stories we worked on were broken down too much, and the solution was to broaden them to get a more global outlook at our designs. And at times it was different enterprise scrum teams in the same projectt, conflicting with different technical framework uses and approaches.
It is only a problem, if you ignore the technical EPIC user story or guideline.
Here is one Agile approach to solving this:
During Agile Release planning, instead of just coming up with a Business EPIC User Story, also come up with a Technical EPIC User Story. The Technical EPIC User story would have the product vision from a technical stand point, in terms of technical architecture, application framework, quality standards, and global design considerations etc. These could be broken down into smaller technical user stories, and have a Scrum Team which works on getting those user stories working. An example of a user story could be: "As a Technical Project Manager, I want the whole enterprise project using A, B, C framework, and coding as per X,Y,Z coding standards, so that there is uniformity in project development work.
If you don't want to form a scrum team separately for this, then just keep them as reminder cards next to backlogs for development teams to use as guidelines.
As a testing guideline, we used to have successful integration testing as a done criteria for each backlog. A global test was conducted in an integration environment, on all working software deployed from all enterprise teams, to deem it shippable. So right from inception to end of the backlog, the theme is set for global working software and not just local working software.
Finally, Agile development involves keeping a constant eye on quality, and one of the quality issues could be bad design or a too localized design. As and when this is discovered, it should be redesigned within that backlog itself, and followed going forward for other Backlogs.
我曾经参与过一个项目,就遇到过这个问题,但没有有效地处理它。
代码的本地质量(例如,在包的规模上)还不错。但在更大范围内也存在问题;例如包之间的逻辑(而不是代码)重复、使用批量重新计算作业(我们应该使用事件驱动的方法)、在错误的位置将系统拆分为单独的服务等。
这些问题都无法通过重构来解决单个类或包。结果,这些事情在正常情况下从未发生过。我们进行了较小规模的重构——添加功能时,我们会在开始之前在该区域进行重构,并在完成后再次进行重构(以及在我们进行过程中努力编写好的代码)。但这从未导致重构更大的架构问题。
我们都意识到了这些问题,只是我们的流程中没有任何东西可以让我们解决这些问题。
我们确实取得的一项显着胜利是两个关系较远的模块之间存在重复。本质上,有一些代码可以呈现一个网页,显示一组计算的结果,还有一个后台作业来生成执行类似计算的报告。计算代码是共享的,但设置计算的代码不是共享的;一个是由用户的视图首选项驱动的,而另一个是由配置的报告作业驱动的。我们需要实现一个功能,该功能涉及向计算添加新的方面,这意味着向两种配置添加更多项目,然后向两组计算设置代码添加业务逻辑。我们设法让产品经理(我们的客户代理)同意为工作预算足够的时间,我们可以重构以统一用户视图首选项和配置的报告工作的想法,因此扔掉重复的一侧,然后实现该功能。这比仅仅实现两次花费的时间更长,但产品经理足够明智,他意识到这将使我们更快地实现跨越页面和报告的未来功能。
我们这样做的过程中的机制是为重构工作编写故事。本质上,类似于“作为产品经理,我希望页面和报告使用通用的计算设置代码,以便我可以更快地添加功能”。这绝对不是一个合适的故事,但它适合系统,并且完成了任务。
我想,如果这个项目运行得健康一点,这样的故事就会源源不断地出现。我们承认我们有很多架构债务,而且偿还债务的工作是有价值的,并为此分配固定比例的时间,也许大约 20%(这实际上意味着一次一对)。然后,我们可以生成功能/史诗、故事和任务,就像我们为面向客户的工作所做的那样。这些将来自团队本身,而不是产品经理。
遗憾的是,开发和产品管理双方之间没有足够的沟通和信任来保证这是可行的;我们可以对产品说,我们遇到了一个问题,这个问题很重要,而且需要很长时间才能解决,而他们不知道这是否属实。因此,他们通常不愿意安排时间来做这件事。可悲的是,每个人都同意存在问题,解决这些问题会很好,但我们只是在实际执行方面陷入了僵局。
I've been on a project which has had this problem, and has not dealt with it effectively.
The local quality of the code - over the scale of a package, say - was not bad. But there were problems at larger scales; things like duplication of logic (but not code) between packages, use of batch recomputation jobs where we should be using event-driven approaches, splitting the system into separate services at the wrong place, etc.
None of these problems could be fixed by refactoring a single class or package. As a result, they never happened in the normal course of events. We did refactorings at smaller scale - when adding a feature, we'd refactor in that area before starting, and again after we finished (as well as making some effort to write good code as we were going). But that never led to refactoring larger, architectural concerns.
We were all conscious of the problems, we just didn't have anything in our process that let us fix them.
One notable victory we did have was where there was duplication between two distantly related module. Essentially, there was code to render a web page showing the results of some set of calculations, and also a background job to generate reports doing similar calculations. The calculation code was shared, but the code to set up the calculations was not; one was driven by a user's view preferences, whereas the other was driven by a configured reporting job. We had a feature to implement that would have involved adding a new aspect to the calculations, which would have meant adding more items to both kinds of configuration, and then adding business logic to both sets of calculation setup code. We managed to get the product manager (our customer proxy) to agree to budget enough time for the work that we could refactor to unite the ideas of user view preferences and configured reporting job, so throwing away one of the sides of the duplication, then implement the feature. This took longer than just implementing it twice, but the product manager was wise enough to realise that this would let us implement future features spanning both pages and reports more quickly.
The mechanism in the process by which we did this was writing stories for the job of refactoring. Essentially, something like "As a product manager, i want pages and reports to use common calculation setup code, so that i can get features added more quickly". This is absolutely not a proper kind of story, but it fitted in the system, and it did the job.
I think that if the running of this project had been a bit healthier, then there would have been a steady stream of stories like this. We would acknowledge that we had a lot of architectural debt, and that work to pay it off had value, and allocate a fixed fraction of our time to it, perhaps about 20% (which would really mean one pair at a time). We could then have generated features/epics, stories, and tasks just as we did for customer-oriented work. These would originate from the team themself, rather than the product managers.
Sadly, there wasn't quite enough communication and trust between the development and product management sides that this was feasible; we could say to product that we had a problem, it was important, and that it would take so long to fix, and they couldn't know if that was true or not. As such, they were generally unwilling to schedule time to do it. The sad thing was that everyone was in agreement that there were problems and it would be good to fix them, we just had an impasse over actually doing it.
根据我的经验,如果您正在处理具有固定时间/要求的项目环境,那么是的,大多数时候敏捷会导致局部最优。
但我的观点是,在复杂的工作中,需求、团队本身甚至目标都会发生变化。敏捷还意味着拥抱变化。
然后,矛盾的是,在处理移动目标时,这种贪婪策略成为全局优化的合理选择。
in my experirence, if you´re working a project context with fixed time/requirements then yes, most of the times Agile leads to local optima.
But my point is that in a complex endeavour, the requirements, the team itself and even the goals change. Agile is also about embracing changes.
Then, paradoxically, this greedy strategy arrises as a reasonable option for global optimization when dealing with moving targets.