- Korea times
- 끌리면 오라...BGM 광고음악 라이브러리
- KartOO visual meta search engi…
- E-Book
- Channel9
- MSDN
- 여리의 작업실
- 유경상의 .NET 블로그
- window 쪼물딱 거리기
- 블루 홈(소현이 누님)
- IT 관련 전반 내용(정환이네)
- 비너스의 정보 공유(유틸리티들)
- 형기의 자료공간(디지털ERA에서 콘텐츠ERA로)
- EzineArticles (여러 분야의 글들이 올라옴)
- Relationship을 보여주는 라이브러리
- OpenRCE
- 젠틀의 블로그(무선 통신의 모든것)
- 헐랭이와 IT보안
- 워니. 추억ㅇㅔ ㅂㅣ추ㅇㅓ.
- Computer Forensics
- 토익 광장(YBM)
- Korea Times 이용하기
- Larkware Software
- TCP/UDP
- Black Hat
- DEF CON
- Slashdot
- ReallyUsefulEbooks.com Update
- 실리콘밸리 뉴스
- Application Development Trends
- Visual Studio Hacks
- MIT OCW
- Redmond Developer News
- SecurityFocus
- Microsoft Window Hacking Porta…
- Darknet - Don't Learn to Hack …
- Windows Tips, Tricks and Hacks
- Hack In the Box
- (IN)SECURE Magazine
- SuperSite Windows Vista
- Government Security
- Life is Still Talking (Good)
- PHRACK
- Found+Read(resource for startu…
- Jonathan Boutelle
- Venture Hacks
- 스마트플레이스
- All about Intellipedia
- Undocumented Windows 2000 Secr…
- HexBlog (Decompiler)
- TED (Ideas worth spreading)
- Crash Dump Analysis and Debugg…
- Rootkit
- DDK Developers(MS)
- 미친 감자의 블로그
- The Art of Assembly Language
- Chpie (키보드 후킹)
- Drivers Online
- (음악) Delicate SONG
- Reverse Engineering Community
- Software Best Practices
- Sara Ford's WebLog
- Cheat Happens
- Debugging,Unpacking,Assembling…
- 윤석찬님 블로그
- OK 괜찮아 다 잘 될거야
- RingBlog
- Art Life :: 하늘소
- IT's Paradise
- John Robbins!
- Wintellect
- Hacked Gadgets
- 소프트웨어 이야기
- Ryan Naraine's Zero Day
- VULN
- Stay Secure
- EBS 영어 공부(블루워터)
- 101BLoG : "Bright Size Life" o…
- Hacker Challenge
- Hackers Center
- White Hat, Chicago Con
- Ethical Hacker Network
- ChaseNet (Security)
- TechTarget
- Entrepreneur
- Infopackets
- Popular Science
- Dark Reading - The Business of…
- How Stuff Works
- codeDriver - Crack (역공학)
- Gadget (Windows)
- Serious Code
- Iguacu Blog(블루문)
- SecurityProof
- Power of Community(Hacker)
- Crack ?
- Security Freak
- Data Network Resource
- FoundStone - Security Consulti…
- Google Online Security Blog
- (BOOK) Cool DogBooks
- SachaBarber (좋은 개발자)
- System Software Incorporation
- 스카이 벤처
- NewsTorrent
- 글로벌 IT 네트워크
- Ethical Hacking and Infosec
- Realms of Hacking tricks
- CodeBreakers Journal
- Anti Rootkit Blog
- The Reverse Code Engineering C…
- Anti-Debug Tools
- Reverse Code Engineering Video…
- Damn Vulnerable linux
- Security Problems
- French Reverse Engineering Tea…
- Monac
- Open Source Vulnerability Data…
- Viruschaser 검사(바이러스)
- Windows Tips
- 보안 대처 연습
- [Download] Kartz CD
- [Download] FlMS Download
- [Download] DDL2
- 중국 해킹 사이트(안전중국)
- 바이러스 분석
- Javascript 전문가
- Virus Alert Zone (바이러스 분석)
- Computer World
- 문스랩닷컴(보안)
- Unpack China
- Black Storm Reverse Engineerin…
- 역공학 Reverser
- 문화 망명지 - 시, 소설
- WPF MVP
- Research Channel
- The Problem Solver - C# MVP
- Reversing - 리버스 엔지니어링
- Nigel Spencer's Blog (.NET)
- Kirill Osenkov (.NET C# IDE Te…
- H33T (BitTorrnet 검색 사이트)
- ITL (해킹, 보안)
- ITL (Invisible Things Lab) Blo…
- ebook, pdf, chm
- 주식 - 멘토클리닉
- CherryLove - 바이러스, 백신, 악성코드
- PMP
- 영원한 해커, hacker
- 리버싱, PE
- 신호철 - dsphome
- TechEd 2009
- SHOUT
- [도서] 오디오북
- [도서] 전자책
- [도서] 국내도서요약
- [도서] 해외도서요약
- TopCorder - 프로그래밍 연습
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- debugging
- 디버깅
- Microsoft
- 책
- 역공학
- 비주얼스튜디오
- Visual Studio
- Windows
- visual studio 2010
- 해킹
- 마이크로소프트
- hacking
- 닷넷
- 디버그랩
- 비주얼 스튜디오
- .NET Framework
- Windows 7
- .net
- .net framework 4
- 보안
- 구글
- MVP
- english
- WPF
- security
- VSTS 2010
- VSTS
- C#
- Today
- Total
NaggingMachine
Real programmers don't use refactoring tools 본문
제목이 좀 특이하죠? 내용과 정반대되는 제목입니다만.. 많이들 사용하는 표현입니다. ㅋㅋ (Real Men Don't Eat Quiche" 에서 유래). Refactoring Tool의 유용성을 역설하고 있는 글입니다. 한번 읽어보시죠~
You know, it's funny. I can well remember the day I saw my first syntax-highlighted code in an IDE. It looked a little weird compared to the flat Notepad look of yester-editors, but, from that point on, non- syntax-highlighted code just became harder to read. It was as if we had been shown the z-axis from having lived in Flatland for so long.
And then came code completion lists. You'd be typing along and if you suddenly became stuck trying to remember a member name, you could wait half a second or so and a list would pop up showing the identifiers you could type in at that particular spot. And again, you were shown another dimension to your code, and there was a split from the past.
And now I see comments like this: "I have to laugh when I see what these tools do. Any coder worth his salt will be instinctively writing code as good as if not better than this tool produces." In case you hadn't guessed, the writer was talking about refactoring tools. In particular, the fake Yorkshireman macho-ness ("When I were a lad, we were lucky to 'ave _fastcall") that infuses the prose might have indicated to you that he was a C++ programmer, and you'd have been right.
This just seems nutty to me and it's not because I work for a company that puts out a refactoring tool. Yes, we all know what refactorings are, the great geek god Martin Fowler wrote a best-selling eponymous book on them. And we all know the names of the most popular ones: Extract Method, Inline Temp, Extract Interface, Move Method, Rename Identifier, and so on. Their names have become a mantra almost, a paean to the new agilism. But, surely -- he says in a baffled voice -- having an automated tool is better than doing them by hand? Aren't refactoring tools just another small step on the way to better visualization of our code and of writing it better and faster? What am I missing that this comment writer implicitly understands, or, rather, vice versa.
The writer of this comment also seems to imply that Code, Once Written, Is Never Changed. It must have been the eleventh commandment, but God ran out of ink when printing it on the stone tablet. But we all know from our own experience, without recourse to statistics, that most code is changed. No matter how good we are, how much we're worth our salt, no matter what language we use, we introduce bugs when we write code. It may be we change it immediately ("Duh, that should be a less than, not a greater than") or it may be later, after testing. And, sure, when we modify our code, or we modify someone else's (because we are lucky indeed if the only code we ever work on is our own), we make use of refactorings as we make fixes.
Think of it like this. Since code will get changed (there's a bug; the requirements change; you prefer to code in an organic fashion as if you were playing with Play-Doh), why not take advantage of a tool that helps you do it? Certainly you can do it all by hand and have members of the opposite sex swoon as they watch you manipulate the code with the keyboard, but to be honest who gives a damn.
I think of the way I write code. I'm an experimentalist developer: someone who develops with TDD (Test-Driven Development). Despite years of programming, I always approach a programming task as a blank sheet of paper. Since I do TDD my blank sheet of paper always starts off with something I'd like to be true (my first test). And then I write the code that satisfies the test, and then I write something else I'd like to be true (another test), and I write more code that makes it so. And so on so forth.
During this continual piecemeal advance towards software of value, my code is completely malleable. Just because I wrote it one way for one test, doesn't mean that it's going to stay that way for ever. I refactor ad nauseam and utterly rely on my refactoring tool to do that.
The refactorings I use most of all are these:
1. Rename Identifier. This one is the most important refactorings in my ever so humble opinion (it's my blog so what I say goes!). When I'm coding, I never seem to get the names of things right the first time. Indeed, I've given up trying to, since it just interrupts the flow of getting an algorithm down. And the names of things are perhaps the most important thing about our code. We can't do anything about the syntax of our language, but, by gum, we can about our identifiers. Name them badly and we obfuscate our code quickly. We've all heard the (apocryphal?) stories about programmers coming across some code where the previous programmer in an effort to be funny used names of flowers or mountains to name local variables.
Compilers don't give a fig about what you name your identifiers. It's your human audience that does, and you can guarantee you'll have one: the hapless maintenance programmer that follows in your footsteps, which, sometimes, is you. You are writing for your human reader first, and your compiler second. Beware if you think it's the other way round, because you'll appear on The Daily WTF. I've learned that the real name for an identifier only becomes obvious once you use it. Sometimes if you find it hard to name an identifier it indicates that your code is not expressing the problem domain properly. So, being able to rename an identifier, without worrying about search-and- replace destruction, is a boon beyond compare.
2. Extract Method. I'm an advocate of small, low- cyclomatic-complexity methods, and ones that have a single responsibility. Ditto for classes, by the way. But constructing a set of interacting methods as a complete thought exercise and getting them all down in source code is a talent that has always eluded me. Call me a stream-of-consciousness programmer by all means, but that generally means slamming it all down and then sorting out the mess afterwards. This is where Extract Method come into its own. Hey, that code over there is essentially the same as this over here, let's extract it into a common method that can be called (reused!) from both locations.
And an automated Extract Method is great: it works out the parameters, constructs the right method signature, inserts calling code at the location where the code was extracted, and in less time it takes to think about the possibility. Toss in a few Rename Identifier refactorings and your code becomes more readable and simpler to understand.
Mind you, me, I can't wait for a tool that will find duplicate code for me. Oooh, at that point the combination may topple Rename Identifier from the top of the list.
3. Create Method Stub. This isn't really a refactoring per se (it makes temporarily non-compilable code into compilable code), but it's so handy for TDD enthusiasts. You're writing a test that defines how you'd like something to read and to work and you find you've used a method name that doesn't exist yet. Hit the refactoring key, and boom, the tool adds a stub method to the right class. Invaluable.
4. Decompose Parameter. This one is rapidly moving up the list ever since I started playing with an early beta version of it from Refactor! Pro. The set up for understanding why this is so good is a little long-winded, but the payoff has all the more impact for it.
When we use a framework like the .NET Framework we find ourselves writing a lot of event handler code so that we can get called back from the framework when something happens. Oftentimes, we'll get a nice handy object passed in as part of the call containing property values we can use in our handler code. The unfortunate thing is these event handlers tend not to be reusable, because the caller has to construct a new handy object to pass in some values. All in all a pain. Especially so when, in general, we are given a particularly rich or heavy object and we only use a couple of its properties. Far better to extract out the specific code into another method, pass in the property values (and not the rich, heavy object), and reuse this new method, including calling it from our event handler.
Enter Decompose Parameter: it works out what's actually being used inside the method's implementation and constructs a method that has those properties as parameters. It then patches up the calling code and you're done. So, instead of a non-reusable event handler that needs an EventArgs but just uses the EventArgs' Graphics property, and hence that requires an EventArgs object to be set up before calling, you get a method that expects a Graphics object instead, and can be used from other painting methods, for example.
5. Move Type to File. One of Refactor! Pro's invaluable refactorings and every time we demo it, people in the audience "get it" immediately. The way we write code these days is to have one class per source file, the latter named after the former. Makes it easy to find the code for classes, and great for when you have multiple programmers working on the same team. But writing code in that way is a pain in the neck. You want a new class, but have to stop what you're doing in order to add a new file to the project, name it accordingly, switch to it, add the new class, switch back to where you were, etc. It's a complete drag to productivity. For the past couple of years, I just continue writing code to build a class model in the same one source file. When I'm ready to extract the classes, I just invoke this refactoring on one class after the other. Boom, boom, boom. Much easier.
6. Extract Interface. Another great refactoring. You've written a class believing it to be the only one you'll need, and, wham, you discover another exemplar that's slightly different. I much prefer interface inheritance to implementation inheritance, and so I'd be doing an Extract Interface so quick it would make your head spin. Mock me, baby.
7. Inline Temp. A quick simple refactoring, nevertheless very useful. It changes code that declares a temporary variable, sets it, and then uses the variable in an expression. This refactoring just gets rid of the temporary variable and moves the initialization into the expression. Sometimes this can make the code a little clearer. Sometimes it won't and you'll need the opposite refactoring; Introduce Temporary Variable. I do tend to use both as I polish code.
8. Use String.Format. Another refactoring that audiences at demos instinctively "get" and that I use all the time. Face it, writing a String.Format call is great for localization efforts, but it's just a real pain to write. It's much easier to write an expression that consists of a bunch of string concatenations, but unfortunately that's hopeless from a localization viewpoint. So, do the easy thing and let the refactoring tool do the tedious work. I love just writing a string concatenation expression, getting it exactly the way I want it, and then convert it to a String.Format call as if I'd done it that way all along.
I'll stop there. My intent here is not to list out all the refactorings I use, only those I use most of all. In doing so, I wanted to indicate why I think a refactoring tool is deserving of being in your coding environment.
Sure, the refactorings I've listed can all be done by hand. Indeed if I were stern and hard-core I'd say do them by hand a couple of times so that you get a real feeling for what each refactoring means and how it works. And I'd laugh my evil taking-over-the-world laugh while you did so. Afterwards you'd just use the automated tool and be thankful that you can save time.
Because in the end, we're not all great programmers who write code correctly in the first pass. We're all programmers writing code to enhance/fix/extend existing code (and even green field projects turn into a marathon of altering code). We're all maintenance programmers to a smaller or larger extent. We're all programmers who have to live with other people's code, and recognize that our code after a few months could be someone else's. And because we're all that and more we deserve the best coding tools we can get. And that includes automated refactoring tools.
'TechnoBabbler' 카테고리의 다른 글
Black Hat과 Defcon 세미나 자료가 올라왔습니다. (0) | 2007.08.27 |
---|---|
Useful Software (0) | 2007.08.24 |
.NET Coding Guidline (0) | 2007.08.23 |
How To Boot From A USB Flash Drive (0) | 2007.08.19 |
RAIDE: Rootkit Analysis Identification Elimination (0) | 2007.08.19 |