Trained 10,000 developers since 1990 Author of the book Beyond Legacy Code: Nine Practices to Extend the Life (and Value) of Your Software Website: http://ToBeAgile.com Twitter: @ToBeAgile デビッドスコットバーンスタイン
Legacy Code Nine Practices to Extend the Life (and Value) of Your Software 」(邦訳:レガシーコードから の脱却) の著者 Website: http://ToBeAgile.com Twitter: @ToBeAgile デビッドスコットバーンスタイン
Nine practices to design and build healthy code, plus some tips on dealing with legacy code. Discusses the value and reasoning behind the technical practices, so both managers and the team can get on the same page as to their value. It’s not a “How To” book, it’s a “Why To” book. 本:レガシーコードからの脱却
teams are doing Scrum? • More than a year? Two? Five? Seven? • How many of your teams are doing XP? • More than a year? Two? Five? Seven? • Which technical practices? • CI, TDD, refactoring, pairing? “This book shows readers how to use SCRUM, an Agile software development process, to quickly and seamlessly implement XP in their shop-while still producing actual software. Using SCRUM and the Agile process can virtually eliminate all downtime during an XP implementation.” “Agile Software Development with Scrum” -- Ken Schwaber and Mike Beedle ? あなたへの質問
With a Product Owner defining the next most important features to build, the need for upfront requirements goes away. 2. Build in Small Batches: Building incrementally increases feedback, helps simplify the construction of complex systems, and reduces risks. 3. Integrate Continuously: Sets up the infrastructure for incremental development. 4. Collaborate: Pairing, mobbing, spiking, and swarming as a team to solve problems and radiate knowledge throughout an organization. 5. Create CLEAN Code: Share standards and practices for building software with code qualities that support testability. 6. Write the Test First: Drops the cost of building and maintaining software dramatically. 7. Specify Behaviors with Tests: Uses tests to define and document behaviors. 8. Implement the Design Last: Paying technical debt can pay back dividends in the short term as well as the long term. 9. Refactor Legacy Code: Incorporate learning and pay off technical debt. Nine Essential Practices 9つの基本プラクティス
painful so teams put it off to the end of a project. A better alternative is to integrate continuously, whenever even the smallest bit of functionality is added to the system. I have a friend who works in an XP shop and I remember when he took me on a tour after hours. He said, “Let me show you what happens if someone breaks the build.” He typed a few lines at the console and suddenly all the florescent lights on the floor when out and a red light started flashing and sirens went off. He said, ”This is what happens when you break the build. We don’t allow broken builds in this shop.” That’s how ingrained a working build is in their culture. プラクティス3 - 継続的に統合する
the dynamic of development. You always have a buildable system so you know exactly where you stand. When developers get instant feedback if something they did during the last few minutes caused a defect then they can quickly and easily back out those changes. But when a simple little defect goes unnoticed for days or even weeks then it can take hours, if not days to track down and fix. We can use the feedback from continuous integration to gain valuable insights into improving how we code. Once set up, continuous integration becomes a source of rich feedback for developers. プロジェクトのハートビート(鼓動)
of done: – Done: The developer who wrote the feature got it to work on their computer. – Done-Done: The feature is integrated into the build and is working. – Done-Done-Done: The feature is integrated into the build, is cleaned up and made supportable. We want to strive to get each feature to done-done-done as soon as possible so we get faster feedback and have less work-in- progress. Done(完成)には三種類ある
deploy. It means you can deploy whenever you want to. When you deploy is a business decision based on product cycles, maintenance contracts, etc. Continuous deployability means you could deploy at any time that the business desires. This drops the risk of building features because you can see each feature integrated into the system and it gives developers feedback as they build features. Make sure you version everything your build depends on including build scripts, stored procedures, database layouts, etc. 継続的にデプロイ可能であること
fast (within a few seconds) and is easy to invoke (with a single click). Slow tests are the main reason for slow builds. Speed up tests by only testing what’s needed and mocking out dependencies. Your build will reveal your dependencies and whether you have a good architecture or not. If the build breaks, then fix it immediately. ビルドを自動化する
code all the time, several times a day. Integrating each little bit of functionality as it is written to be sure the code works with the rest of the system. Being able to prove the system is still working with the click of a button is like a shot of espresso, it energizes me. 早めに、頻繁に統合する
most valuable practice for building software and is often an easy practice to implement. Continuous integration provides the infrastructure for the other technical practices. It may take some work up front to set up but it pays for itself many times over during the life of a project. For a lot of teams, CD is the next most valuable step. Even teams that are doing it can do it better, and by better I mean integrate more frequently. I know developers who run their local build every 20 seconds when developing. That’s a huge amount of feedback they get. --- 最初の一歩を踏み出す
happen. It requires skills and the right environment to flourish. We can set ourselves up for successful collaboration by learning these skills. We can learn from each other and there’re techniques we can use to help us. When I was a contractor at IBM, we were thrown into a big room with desks smashed up against each other. They called it the “bull pen.” IBM Employees got their own offices but they were always amazed at how much we got done. This was partly due to working so closely together. プラクティス4 - コラボレーション
and Ron Jeffries developed Extreme Programming while working on the Chrysler Comprehensive Compensation System. Notice how the work area in the photo is open with lots of whiteboard space on the walls and pairing stations at every computer. Isolating people in offices may not be the best way to encourage collaboration. Open workspaces work well. Menlo Innovations converted a parking garage into a large open workspace where several development teams can work together エクストリームプログラミング
social activity. We must have a shared understanding of our goals and approaches to developing software. We must have a shared definition of “quality” and of when we will be “done.” Developing software is a collaborative act. People say us nerds are bad communicators. I disagree. We may not always like small talk but we love high-bandwidth communication and we’re good at it, it’s part of our job. コミュニケーションとコラボレーション
most valuable practices that I get the most resistance from both managers and developers. Managers tell me they don’t want to loose half their “resources” but pair programming isn’t taking turns at the computer, it’s bringing two minds to bare on tough problems. When pairing, problems are solved faster, with less code, fewer errors, and costs only 15% more dev time. Pairing is the fastest way to propagate skills across a team. People who pair are less likely to be interrupted, stay on task, support each other in doing the right things, and are constantly learning. When I finish a day of pairing I’m exhausted yet supremely satisfied. And this is why you managers should support it. ペアプログラミング
The driver is at the keyboard, the navigator is thinking about what’s next. Pair randomly with everyone on the team. Switch driver and navigator every 5-20 minutes or when the other person is bored. Sometimes I can’t convince a team to try pairing so I suggest buddy programming. Buddy programming is less extreme than pair programming. In buddy programming, developers work alone for most of the day then get together with their “buddy” for the last hour of the day to code review the day’s work. As with pairing, it’s good to mix it up and have a different buddy daily, at each iteration, etc. バディ・プログラミング
or a few people research unknowns in a fixed time box, usually to answer specific questions. Swarming is when the whole team works together to solve the same problem. Mobbing is when the whole team works together on the same story. This is a still from a video you can watch at MobProgramming.org where an 8-hour workday of a team mobbing is compressed down to 5 minutes. You’ll see everyone engaged the whole day. They made great progress on certain kinds of task with mobbing. スパイク、スウォーム、モブ
phrase questions so they clearly identify what is known from what is unknown. Do this by: – For a specific period of time (an hour, day, week, etc.), research answers to your questions. At the end of the time box, reassess your goals. Did you get answers to your questions? Do you have new questions? Do you need another time box? This approach helps you shrink the unknown into the known or, at the very least, you can encapsulate what you don’t know so you can easily deal with it later. 未知のものを調べるタイムボックス
even if you do pair programming. Code reviews let the rest of the team see your code. Focus on describing the reasoning for your design choices rather than just saying what you’re doing. Retrospect regularly to gather feedback and find ways of improving. It’s better to make many small improvements throughout the year than to try to make a lot of big improvements at once. コードレビュー、レトロスペクティブ
help others. That’s job security today, not by having specialized knowledge. Team members should be cross-functional. Teams should practice collective code ownership so everyone can work on any part of the code. Pairing and mobbing are the most effective ways of propagating new skills across a team. 学びを増やす
says. “Always strive to be mentoring someone and to be mentored by someone.” As a teacher myself for over nearly half a century I can say that teaching is one of the best way to learn. The most successful teams I know have pairing at the core of their culture and take time to know what everyone is doing. メンタリングし、メンタリングを受ける
infer good development principles and practices through five key code qualities: – Cohesive – Loosely Coupled – Encapsulated – Assertive – Nonredundant These five code qualities and their relationship to testability underlie all good developer principles and practices. We can infer the right things to do from these five qualities. プラクティス5 – CLEANなコードを書く
cohesive, meaning it’s about one thing. Cohesive classes and method follow the Single Responsibility Principle and have only one reason to exist and therefore one reason to change. As my esteemed colleague Dr. Daniel Rawsthorne says, “No schizophrenic classes.” Al Shallow says, “No God objects.” Scott Bain says, “Keep entities single-minded.” So then how do we model complex things? The answer is to compose complex classes from simple classes. 高品質なコードは凝集性が高い
for no coupling in a system. A system with no coupling is a system that does nothing. We want coupling were we intend it to be and no coupling where we don’t intend it to be. For this reason, I prefer the terms: intentional versus accidental coupling instead of the terms loose coupling versus tight coupling. High quality code is intentionally coupled so it doesn’t call concrete classes directly. Coupling through abstractions makes code easier to test now and extend later. Keep all external dependencies loosely coupled. Coupling is a “second-order effect” so poor coupling is a sign that the other code qualities are missing. 高品質なコードは疎結合である
encapsulated so it’s implementation is hidden. Well-encapsulated code is designed from the outside-in rather than inside-out. We can encapsulate much more than state and behavior, we can encapsulate sequence, cardinality, selection, etc. There are many ways to encapsulate things, we can hide an implementation behind an interface, we can hide a concept behind an abstraction. Design patterns encapsulate many different things. Encapsulation means hiding the how with the what. The art of being a great developer is to hide as much as possible while still getting the job done so you can easily change things later. 高品質なコードはカプセル化されている
assertive, it manages its own state. Assertive objects are be in charge of themselves. Inquisitive objects must query other objects to do their work. This cause rules to be spread out and they become difficult to follow. Keep responsibilities well defined and remember, he who has the state should have the responsibility. 高品質なコードは断定的である
nonredundant, it doesn’t repeat itself. High quality code is nonredundant, it doesn’t repeat itself. Unintentional redundancy is always a maintenance issue. Redundancy is far more subtle than just duplication. – Can non-identical code be redundant? Yes, think of a for loop and foreach loop iterating through the same collection. – Can identical code be non-redundant? Yes, think of “index++” accessing a list of names or a list of numbers. Redundancy is about intent—trying to do the same thing in more than one place. 高品質なコードは冗長でない
it’s easier to read, understand, and find bugs because each entity is dealing with only one thing. When code is loosely coupled code is more straightforward to test and extend and we see fewer side effects between entities. When code is encapsulated it reduces the “ripple effect” when changing code and helps us manage complexity. When code is assertive its data and the code that act on it are together. When code is nonredundant it means we only have to deal with changing code or fixing bugs in one place. コード品質は私たちを導く
the so called “quality factors” or the “-ables” as I call them. For example, “maintain-able.” If I tell you your software should be maintainable I haven’t helped you much. I haven’t told you how to do what I’ve told you to do. These qualities are actionable and quantifiable. You can see if a piece of code has them or not and how to improve them. The only way I know to go fast is to go CLEAN. These code qualities seem simple, almost trivial but when ignored we quickly end up with at “big ball of mud.” If you want to increase your team’s velocity tomorrow you must increase your code quality today. There are no silver bullets! …今日、 品質を上げる
people say TDD is dead because it forces you to write bad code and they’re right but that’s because they’re doing TDD wrong. “Test-induced damage” comes from writing too many tests and implementation dependent tests that not only “damage” software, they also impedes refactoring. But when done correctly, TDD helps us write CLEAN code that’s more maintainable. The key is understanding what TDD really is. プラクティス6 – まずテストを書く
represents many things in software development: • Acceptance tests are customer tests, they help clarify the conversation between the customer and developers. • Unit tests are developer tests, they help developers build out features so they’re testable and easy to work with. • Other tests are quality assurance tests, they help verify the software is bug free. • Each of these activities are very different from each other. 私たちがテストと呼んでいるもの
can help. There are many kinds of QA testing but for our purposes let’s break it out into two categories: – Release candidate validation – Everything else Make release candidate validation fully automated so it requires no human intervention. Let QA focus on other kinds of testing. 品質保証(QA)
to write a good test and do TDD effectively but that’s rarely the case. Think of tests as specifications for the behaviors that you want to create. Make tests unique and only write enough implementation to make your tests pass. The “units” we test are units of behavior, not units of code. When we refactor to implement our designs, we don’t need to add more tests, the ones we have are sufficient and support us in refactoring. Only when we add new behavior should we add tests. 良いテストを書く
found the cheaper they are to fix. Good tests provide regression that is a constant source of feedback on the system. When developers run their tests all the time they get rapid feedback on what works and what causes problems. The same issues that could have taken days to find and fix can typically be resolve in a matter of minutes. When stimulus and response are brought together developers begin to change their habits and write higher quality code. The top developers I know get feedback about 3 times a minute. TDDは迅速なフィードバックを提供
a discipline when he published the book Refactoring: Improving the Design of Existing Code. Refactoring is changing the code without changing the behavior. Why should we do it? Refactoring lets developers have another chance to clean up their designs and make the code easier to work with in the future. When adding features it is often more straightforward to refactor and clean up the code first. “Clean the kitchen before preparing the dinner party.” TDDはリファクタリングを助ける
TDD or not, you should always write testable code. If I can write a test for something than typically I understand it enough to start coding it. If I can’t then I need to think more before coding. Doing TDD helps keep me moving forward. It validates my understanding and helps me focus on the right things at the right time. I can do TDD in almost any condition, even half-asleep. テスト可能なコードを書く
is, I’ve seen it fail more often then succeed. About 10% of the Scrum community are doing the Extreme Programming practices and most are doing it poorly. When developers write too many tests or implementation- dependent tests, they impede rather than support refactoring. Do not “test until bored.” Don’t put your QA hat on when writing tests. Write only enough tests to create the behavior you want to write. Use TDD to specify behaviors, not to test implementation details. しかしTDDは失敗する可能性があります
to try it and find value in it in order for the practice to take root. It rarely works to have management impose TDD as a requirement to teams without training or ramp up time. To do TDD successfully you must know three things: – Understand TDD as a way of specifying behavior you want to build. – A variety of techniques to make untestable code testable. – An experience of building software test-first. TDDをチームに導入する
“test infected” to describe the passion developers feel for doing TDD. I’m test infected, you couldn’t pay me enough to work on a non- TDD project. That’s how much I value TDD. When developers do TDD they spend far less time doing things they don’t love, like interpreting requirements and debugging, and spend far more time writing code, which we enjoy the most. TDD shows me how to write higher quality code that is more straightforward to extend in the future. “Warning: Promiscuous pairing can lead to becoming test infected.” テストに感染する
ために、十分な報酬をいただくわけにはいきません。それくらい 、私はTDDに価値を感じているのです。 開発者がTDDを行うと、要求の解釈やデバッグといった好きでも ないことに費やす時間が大幅に減り、私たちが最も楽しんでいる コードを書くことに多くの時間を費やすことができます。 TDDは、より質の高いコードを書く方法を教えてくれますし、将 来的な拡張もより簡単にできます。 “Warning: Promiscuous pairing can lead to becoming test infected.” テストに感染する
changing the internal structure of code without changing its external behavior. When I asked my manager to have the whole team take an iteration to refactor their code, how should I justify it? Developers understand the importance of refactoring but we often don’t express it well to the business. Refactoring drops the cost of four things: – Understanding the code later, – Adding unit tests, – Accommodating new features, – Doing further refactoring. プラクティス9 - レガシーコードをリファクタリングする
car and, because you paid so much for it, insist on never taking it to the shop? Technical debt, like financial debt, is costs less the sooner you pay it off. If you don’t address technical debt then every time anyone goes into code they are paying to understand and modify the code. Technical debt can accumulate even when paying attention to principles and practices as we learn more and need to change our designs. 投資か借金か?
cards off in full each month. Credit card companies have a name for customers like me. We’re called “deadbeats” because they don’t make any money on us. A friend once owed $17,000 on a credit card and the notice said if he paid the minimum payment each month that at the end of 93 years he would have paid $184,000. Become a “technical deadbeat” and pay off technical debt as soon as you can. It is the cheapest approach. 「怠け者」になる
does what we want and doesn’t need to be extended then there’s no reason to refactor and clean it up. Refactoring is expensive so, “if it ain’t broke, don’t fix it.” Only when code needs to change do we have to be concerned with refactoring. When refactoring legacy code, use the simple refactorings to introduce “seams” in code so you can add tests to support more complicated refactorings. Refactoring code teaches developers to avoid those kinds of mistakes in the first place, it helps you write better code! コードの変更が必要なとき
and techniques: – Pinning tests: Refactoring code without tests can be dangerous. First, add one big end-to-end test, sometimes called a “pinning test” to pin down the current behavior. Run pinning tests frequently. – Dependency injection: Separate use from creation by building objects in “factories” and inject them as needed. – System strangling: Lets you replace a component while it’s in operation by creating a new implementation that’s called from the old interface. Have new callers use a new interface and slowly refactor old clients to the new interface. – Branch by abstraction: Use feature flags to toggle features and avoid branches in version control so all development is off of trunk. リファクタリング技法
refactoring techniques. It all boils down to this: clean up the code, make it easier to understand and work with, retrofit in tests to make code safe to work with and only then do more significant refactoring. Some of my favorite books on refactoring legacy code are: – Refactoring: Changing the Structure of Existing Code by Martin Fowler – Working Effectively with Legacy Code by Michael Feathers – Behead Your Legacy Beast: Refactor and Restructure Relentlessly with the Mikado Method by Daniel Brolund, Ola Ellnestram 変化に対応するためのリファクタリング
レガシーコードのリファクタリングに関する私のお気に入りの本 がいくつかあります。 – リファクタリング:既存のコードを安全に改善する by Martin Fowler – レガシーコード改善ガイド by Michael Feathers – Behead Your Legacy Beast: Refactor and Restructure Relentlessly with the Mikado Method by Daniel Brolund, Ola Ellnestram 変化に対応するためのリファクタリング
for adding features to existing software: – Before adding the feature, refactor the software to accommodate the new feature. For example, by adding abstractions. – Once the system has been refactored so the new feature can easily be added without changing much existing code, write a test for the new feature, watch it fail, and then make it pass TDD-style. Many developers try to do these two steps at the same time and end up raising their effort and risk. By separating the process of accommodating a new feature from actually adding it, the changes we make to code are less risky and simpler to do. オープン・クローズドのためのリファクタリング
just happen, we have to follow principles and practices that support it. Supporting changeability includes paying attention to code qualities, using the right abstractions, and modeling accurately. Good software development follows certain patterns and sequences that have proven valuable. TDD supports us in writing changeable software and it supports us as we change implementation by telling us the code still works. リファクタリングで変更しやすさを確保する
difficult to abstract from a single example, I wait until I have two or more examples of something before creating abstractions or writing a generalized algorithm for something. This technique is called triangulation and comes from celestial navigation. Just like a point on the horizon can be calculated more accurately with more than one point of reference, we can often see generalizations more easily with multiple concrete examples. Refactoring and emerging designs in this way can a be highly efficient and effective to build quality software. 二度目に正しくやる
the Agile Manifesto is a software developer. To me, Agile software development is summed up best in the first principle of the Agile Manifesto: – “Our highest priority is to satisfy the customer through early and continuous delivery of valuable software.” Successful software development requires a different set of skills than successful manufacturing. It’s about building independently verifiable behaviors that cost less to create and maintain. Just doing the practices is not enough. We must understand why the practices are valuable in order to apply them well. Why? 真のアジャイル精神
to learn more: – Read my blog: http://ToBeAgile.com/blog – Sign up for my newsletter: http://ToBeAgile.com/signup – Follow me on Twitter (@ToBeAgile) – Read my book: – Beyond Legacy Code: Nine Practices to Extend the Life (and Value) of Your Software (available from http://BeyondLegacyCode.com) – Attend my one of my Certified Scrum Developer trainings – See http://ToBeAgile.com/training for my public class schedule – Or contact https://www.agilergo.com/ to arrange a private class – Visit http://ToBeAgile.com for more information ありがとうございました!