One Thing: Extract till you Drop. 209
For years authors and consultants (like me) have been telling us that functions should do one thing. They should do it well. They should do it only.
The question is: What the hell does “one thing” mean?
After all, one man’s “one thing” might be someone else’s “two things”.
Consider this class:class SymbolReplacer { protected String stringToReplace; protected List<String> alreadyReplaced = new ArrayList<String>(); SymbolReplacer(String s) { this.stringToReplace = s; } String replace() { Pattern symbolPattern = Pattern.compile("\\$([a-zA-Z]\\w*)"); Matcher symbolMatcher = symbolPattern.matcher(stringToReplace); while (symbolMatcher.find()) { String symbolName = symbolMatcher.group(1); if (getSymbol(symbolName) != null && !alreadyReplaced.contains(symbolName)) { alreadyReplaced.add(symbolName); stringToReplace = stringToReplace.replace("$" + symbolName, translate(symbolName)); } } return stringToReplace; } protected String translate(String symbolName) { return getSymbol(symbolName); } }
It’s not too hard to understand. The replace() function searches through a string looking for $NAME and replaces each instance with the appropriate translation of NAME. It also makes sure that it doesn’t replace a name more than once. Simple.
Of course the words “It also…” pretty much proves that this function does more than one thing. So we can probably split the function up into two functions as follows:
String replace() { Pattern symbolPattern = Pattern.compile("\\$([a-zA-Z]\\w*)"); Matcher symbolMatcher = symbolPattern.matcher(stringToReplace); while (symbolMatcher.find()) { String symbolName = symbolMatcher.group(1); replaceAllInstances(symbolName); } return stringToReplace; } private void replaceAllInstances(String symbolName) { if (getSymbol(symbolName) != null && !alreadyReplaced.contains(symbolName)) { alreadyReplaced.add(symbolName); stringToReplace = stringToReplace.replace("$" + symbolName, translate(symbolName)); } }
OK, so now the replace() function simply finds all the symbols that need replacing, and the replaceAllInstances() function replaces them if they haven’t already been replaced. So do these function do one thing each?
Well, the replace() compiles the pattern and build the Matcher() Maybe those actions should be moved into the constructor?
class SymbolReplacer { protected String stringToReplace; protected List<String> alreadyReplaced = new ArrayList<String>(); private Matcher symbolMatcher; private final Pattern symbolPattern = Pattern.compile("\\$([a-zA-Z]\\w*)"); SymbolReplacer(String s) { this.stringToReplace = s; symbolMatcher = symbolPattern.matcher(s); } String replace() { while (symbolMatcher.find()) { String symbolName = symbolMatcher.group(1); replaceAllInstances(symbolName); } return stringToReplace; } private void replaceAllInstances(String symbolName) { if (getSymbol(symbolName) != null && !alreadyReplaced.contains(symbolName)) { alreadyReplaced.add(symbolName); stringToReplace = stringToReplace.replace("$" + symbolName, translate(symbolName)); } } protected String translate(String symbolName) { return getSymbol(symbolName); } }
OK, so now certainly the replace() function is doing one thing? Ah, but I see at least two. It loops, extracts the symbolName and then does the replace. OK, so how about this?
String replace() { for (String symbolName = nextSymbol(); symbolName != null; symbolName = nextSymbol()) replaceAllInstances(symbolName); return stringToReplace; } private String nextSymbol() { return symbolMatcher.find() ? symbolMatcher.group(1) : null; }
I had to restructure things a little bit. The loop is a bit ugly. I wish I could have said for (String symbolName : symbolMatcher) but I guess Matchers don’t work that way.
I kind of like the nextSymbol() function. It gets the Matcher nicely out of the way.
So now the replace() and nextSymbol() functions are certainly doing one thing. Aren’t they?
Well, I suppose I could separate the loop from the return in replace().
String replace() { replaceAllSymbols(); return stringToReplace; } private void replaceAllSymbols() { for (String symbolName = nextSymbol(); symbolName != null; symbolName = nextSymbol()) replaceAllInstances(symbolName); }
I don’t see how I could make these functions smaller. They must be doing one thing. There’s no way to extract any other functions from them!
Uh… Wait. Is that the definition of one thing? Is a function doing one thing if, and only if, you simply cannot extract any other functions from it? What else could “one thing” mean? After all, If I can extract one function out of another, the original function must have been doing more than one thing.
So does that mean that for all these years the authors and consultants (like me) have been telling us to extract until you can’t extract anymore?
Let’s try that with the rest of this class and see what it looks like…class SymbolReplacer { protected String stringToReplace; protected List<String> alreadyReplaced = new ArrayList<String>(); private Matcher symbolMatcher; private final Pattern symbolPattern = Pattern.compile("\\$([a-zA-Z]\\w*)"); SymbolReplacer(String s) { this.stringToReplace = s; symbolMatcher = symbolPattern.matcher(s); } String replace() { replaceAllSymbols(); return stringToReplace; } private void replaceAllSymbols() { for (String symbolName = nextSymbol(); symbolName != null; symbolName = nextSymbol()) replaceAllInstances(symbolName); } private String nextSymbol() { return symbolMatcher.find() ? symbolMatcher.group(1) : null; } private void replaceAllInstances(String symbolName) { if (shouldReplaceSymbol(symbolName)) replaceSymbol(symbolName); } private boolean shouldReplaceSymbol(String symbolName) { return getSymbol(symbolName) != null && !alreadyReplaced.contains(symbolName); } private void replaceSymbol(String symbolName) { alreadyReplaced.add(symbolName); stringToReplace = stringToReplace.replace( symbolExpression(symbolName), translate(symbolName)); } private String symbolExpression(String symbolName) { return "$" + symbolName; } protected String translate(String symbolName) { return getSymbol(symbolName); } }
Well, I think it’s pretty clear that each of these functions is doing one thing. I’m not sure how I’d extract anything further from any of them.
Perhaps you think this is taking things too far. I used to think so too. But after programming for over 40+ years, I’m beginning to come to the conclusion that this level of extraction is not taking things too far at all. In fact, to me, it looks just about right.
So, my advice: Extract till you just can’t extract any more. Extract till you drop.
After all, with modern tools it takes very little time. It makes each function almost trivial. The code reads very nicely. It forces you to put little snippets of code into nicely named functions. And, well gosh, extracting till you drop is kind of fun!
I like the 2nd and 3rd iterations best. By the time the last iteration is reached the code feels a lot less compact and succinct. I think that extracting ad nauseum on every method in a class would balloon the size of the class and make it hard to keep all in mind at once.
P.S. It would be interesting to see patch sets with a commit after each change of the full class.
Watch out! Uncle Bob’s coding style is infectious, and there is no going back if you catch the bug!
Readable code has come to mean just that: code that reads naturally. Not just that code is easy to figure out, but that you can read it like English.
What’s not to like?
Following the flow of the data through the fully extracted version becomes difficult, since the developer will need to jump around constantly throughout the body of the class.
If the goal is to make development and maintenance easier and fully extracting the class makes it more difficult for a developer to follow the flow of the data is it better to fully extract just for the sake of following a rule?
As you mentioned, you were looking for support of the Iterator interface on the Matcher class. Creating a utility Adapter to the Matcher class would have moved the responsibility nextSymbol out of this class.
But that isn’t my point.
My point is that patterns in code are easier to see when things are not broken down into such small chunks. At the fully decomposed state it isn’t obvious that an Adapter on the Matcher would simply fit into place. By decomposing the methods so fine you lose context, so much so it isn’t evident how the method relates to the accomplishing the goal of the class.
Two critical issues with over extracting:
1. Extraction takes time. In many cases the first working version of the code is a one, long, do-it-all, method. Only then comes extraction/refactoring. So when you extract you spend time which slows you down. Hopefully, in the long run this slowdown will be worth it due to ease of maintenance, less bugs, etc. Thus, the million dollar question is that of the breakeven point: What is the point after which the benefits of extraction will not match its slow down?
No one can calculate the breakeven point, but nonetheless, it exists. Smart developers try to stay on the right side of this point.
2. A method offers a sense of encapsulation: client code can see its signature, but it cannot see/touch its internals. When a method is decomposed, its internals are exposed as new (extracted) methods. Even if the extracted methods are private, they are still visible within the containing class. Some of them will become protected. Soon, you will lose the ability to modify them since other parts of the code depend on them. In short: extraction implies less encapsulation which implies increased coupling.
This does not mean you should never extract. It just means that you should weigh the consequences before you do so.
Itay Maman:
I agree with your second point.
But your first point does not fly with me. Assuming you are using TDD (which you may not be) you should not wind up with a behemoth method that needs to be decomposed into smaller methods. The decomposition should occur while developing the method. Otherwise you will likely wind up using a ton of copy/pasted code in your test cases as you attempt to handle each branch to make sure the state is correctly setup.
Why should functions do one – and only one – thing? What are we trying to achieve? My answer is readability AND maintainability. If extracting ad infinitum drives your code to less readability, just stop to extract methods.
Kind Regards
I’ve had a similar thought when following the Single Responsibility Principle: extract classes until you can not extract any more.
In my current pet project (http://dimdwarf.sourceforge.net/) that has resulted in very small and focused classes. I feel good about the small classes. On the other hand, when a class begins to approach 200 LOC (Java), it begins to smell and I try harder to find behaviour that could be extracted into its own class. Often times I find something and extracting it improves the design.
Here are some statistics of that project: “On 2009-05-21, the core module has 156 classes of which 75% are
I’ve had a similar thought when following the Single Responsibility Principle: extract classes until you can not extract any more.
In my current pet project (http://dimdwarf.sourceforge.net/) that has resulted in very small and focused classes. I feel good about the small classes. On the other hand, when a class begins to approach 200 LOC (Java), it begins to smell and I try harder to find behaviour that could be extracted into its own class. Often times I find something and extracting it improves the design.
Here are some statistics of that project: “On 2009-05-21, the core module has 156 classes of which 75% are <50 LOC, and 15 classes are over 100 LOC, the longest file being 194 LOC.”
If you find that extracting methods starts to generate too many methods, that’s probably a code smell that you need to start extracting classes from your new methods.
I have rarely, if ever, found code that was over extracted (if that’s even possible). It’s far, far more common to have bloated methods and bloated classes.
Good article Uncle Bob. I had a quick question regarding your replaceAllSymbols function.
Would a while loop be better in this case as you could remove the duplicate symbolName = nextSymbol()? Something like.
Not meant as a troll, just an honest question.
It looks like there’s a bug.
Suppose we have these symbols and replacements:Here are the results of translating two inputs. (I’ve only checked this mentally.)
The order of the symbols in the input determines whether a symbol will replaced once or multiple times in the output.
This is sure to be confusing to a user who stumbles onto it. Doing token replacement by repeated calls to String.replace() isn’t a good idea unless the replacements are hard-coded and you’re careful to think about whether order matters and test any edge cases. It’s good enough to HTML-escape something if you’re careful, but for anything more complicated, better to scan the input and build up the output using a StringBuilder.
Refactoring the code to use smaller methods doesn’t help you find the bug; if anything it obfuscates it by introducing unnecessary abstractions. Better to spend time writing some tests and thinking about how to break it.
Also, the API is a bit odd. From the caller’s point of view, passing the input string to the constructor doesn’t help with dependency injection, so I don’t see an advantage to an API that looks like “out = new SymbolReplacer(input).replace()” versus “out = SymbolReplacer.replace(input)”, and it leaves open the possibility that someone will call the constructor once and the replace() method multiple times, which would result in further bugs and possibly even race conditions if it were done in separate threads. (The use of non-final instance variables in what should be a pure function is a code smell.) It seems like a better approach would be to start out with a single static method, possibly extract other static methods for clarity once you’re sure the code works, and put off creating a real class until it’s more clearly needed.
Just curious. Where is getSymbol defined?
I’m also wondering what getSymbol is, and how it is different from translate.
It’s really interesting reading the stages that you went through from the original code to a stage where every function does exactly one thing. I like the step where you pulled out the nextSymbol() function the best.
Question – how come you instantiate the symbolPattern and alreadyReplaced fields at the same time as the field definition instead of in the constructor as well? Is there some rule of thumb to know when each way is preferable?
If I had to guess at a rule of thumb from the example it would be something along the lines of “instantiate in the constructor if to instantiate you need the arguments of the constructor”. From memory, instantiations at definition time occur between the call to new in the client class and the start of the constructor in the class in question so it’s like they’re included at the start of the constructor without adding to the bulk required to get an understanding of what the constructor is doing.
Note however that symbolPattern is declared final ergo it must be instantiated at definition time.
Also alreadyReplaced is instantiated in the original example so “if it ain’t broke don’t fix it” potentially applies as well.
If the sample had several instances of :-
in it then there’d be an argument to bring the alreadyReplaced instantiation inside the constructor and then extract all 3 lines into an initialiser function (resetSymbolPattern perhaps?) and then replace all occurences with that.
[cough] ok… must fact check next time before submitting.
That statement is not true, you can instantiate final variables in the constructor. I’d probably consider it poor form but it is legal code.
Nothing to see here :)
“For years authors and consultants (like me) have been telling us that functions should do one thing. They should do it well. They should do it only.”
A function by definition, returns 1 result from 1 input. If there’s no reuse, there is no “should”. Decomposition is for reuse, not just to decompose. Depending on the language/compiler there may be additional decision weights.
What I see from the example is you’ve gone and polluted your namespace with increasingly complex,longer,more obscure, function name mangling which could have been achieved (quick and readable) with whitespace and comments. To mirror a previous poster, I rather see a javadoc with proper commenting than to trace what’s going on for such a simplistic case. I’m afraid to ask what you plan to do when the class is more complex and symbolExpression(..) isnt descriptive enough!
Code review often allows other developers to point out “that’s a bit complex”. This doesnt mean “because you can decompose, you should”, but that you need better documentation. Name mangling is not enough. That’s just my experience with very large applications.
While I agree with decomposition is general, I find this excessive for three more reasons:
1. When you read such a decomposed piece of code you find yourself constantly jumping from one place to another in order to understand what’s going on. Having more stuff in one place is easier to understand: our brains are very good at quickly analyzing complex pictures, but bad at following links.
2. Excessive decomposition not only increases the amount of code, but also the number of parameters that need to be passed to helper functions. In the all-in-one-method solution, these parameters are just in scope, so do not need to be explicitly declared.
3. Perhaps most importantly: I often find excessive decompositions very unstable: a requirement change that would result in a small change in the all-in-one solution, often requires a significant refactoring of the decomposed one. One might say that excessive decomposition tries to extracts a structure that is not really there.
This code is smelly to me:
The Composed Method pattern says that all operations in a method should be at the same level of abstraction. But I think that one more principle should be added to it: all operations in a method should be at a lower level of abstraction than the name of the method.
In the above code “replace” and “replaceAllSymbols” are at about the same level of abstraction. Also “replace” does not describe the method as well as “replaceAllSymbols”, so it would be better renamed to “replaceAllSymbols”.
I would prefer the “replace” method to be changed to:
...and with some refactoring, it would read better as:
Brian Slesinsky:
Thanks for finding that potential bug. It’s not an actual bug because in the context of the system in which it was written, symbols can’t contain other symbols. Still, it’s a good spot, and something I should fix.
The API remark is also interesting. This class actually came about through an “Extract Method Object” refactoring. You are probably right that this makes it feel strange.
Reminded me of a quote by Antoine de Saint-Exupery: “A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away.” Had he been into software, he might have said “Extract till you Drop”!
Overall, I agree that extracting smaller methods from bigger ones is a good idea. It improves readability at different levels of abstraction, encourages reuse, and makes it easy to spot subsequent refactorings (move method, extract class, etc).
I cannot agree with some of the comments on this post that suggest javadocs or inline comments instead of decomposing methods: comments can quickly get outdated or become an unnecessary overhead. http://c2.com/cgi/wiki?CommentCostsAndBenefits
Along with extracting methods, I believe the inverse “Inlining methods” is also important at times while refactoring. Depends on where the refactorings take you.
As for this code example, like someone else pointed out, it can lead to unexpected results (at least difficult to track) depending on how many times replace() is called. I’d much prefer such “verb classes” be immutable. I do still prefer that the original string be made a field (final one) injected via a constructor, rather than have a static method that takes the string as an argument, because static methods when decomposed lead to most of the decomposed methods also having the same arguments as the original, and the values need to be passed around (instead of directly being referenced as a field).
I think a functional style is more elegant.
an Erlang implementation:
-module(sr). -export([replace/1]).
replace(Str) -> {ok,MP} = re:compile(”\\$([a-zA-Z]\\w*)”), {match,Matches}=re:run(Str,MP,[global]), replace(Str,[{B+1,L} || [_,{B,L}] <- Matches]).
replace(Str,Indices) -> replace(Str,Indices, 1, []).
replace(,[],,Acc)-> lists:append(lists:reverse(Acc)); replace(Str,[{B,L}|T],C,Acc)-> S1=string:substr(Str,C,B-C), S2=string:substr(Str,B,L), replace(Str,T,B+L,[get_replacement(S2),S1|Acc]).
get_replacement(Symbol) -> ....
I think a functional style is more elegant.
an Erlang implementation:
Hej, Uncle Bob,
Thanks for another, fine post.
I hope you won’t be too bored if I make two points.
Firstly, I tend to agree with Itay Maman’s post.
Encapsulation theory tells us that a benefit of encapsulation is that it minimises the number of potential dependencies with the highest probability of modification event propagation [1].
In his landmark paper on cyclomatic complexity, Thomas McCabe describes source code where, “Each node in the graph corresponds to a block of code in the program where the flow is sequential and the arcs correspond to branches taken in the program.” Thus, we can view a method as encapsulating blocks of sequential code, where only the first block (the default entry-point into a method) is accessible from outside that method, all other blocks being information-hidden.
If all your methods have only one block, then none of the blocks is information-hidden. With n such blocks (and thus n methods), the number of potential dependencies between your blocks will be n(n-1). In your case n=9; so the, “Potential coupling,” as it’s known, will be 9(9-1)=72. It’s possible to calculate the number of methods to minimise this potential coupling; this minimisation occurs when n=3, i.e., with 3 methods (which you had originally, though for minimisation, the blocks must be evenly spread over the 3 methods). At minimisation, the potential coupling will be 36.
If that all sounds like EXTREME, nerdy overkill, then, it is: for a small problem like the one you posted, the semantics will probably dominate; but it is something to think about before making all your blocks accessible to one another within a class.
Secondly, consider how your idea might scale.
It’s easy to view programs as a graph stack; a graph here being a region encapsulating nodes. On the bottom, sequential blocks are encapsulated into methods. At the second graph, methods are encapsulated into classes. At the third graph, classes are encapsulated into packages.
The point is that there’s no reason why the rules for encapsulating one graph should be very different from any other.
Thus if you think that, “Doing one thing only,” implies decomposing all methods in single blocks, then does that mean that all classes should contain only one method, and that all packages should contain only one class?
I’m sure you do not think so, and there may be good reason why this advice holds for block/method graphs but not for method/class or class/package graphs; again, I just wanted to offer some food for thought.
Thanks, again, for the fine post.
Regards,
Ed Kirwan.
[1] http://www.edmundkirwan.com/encap/l2/paper6.html
Great post. I had wondered in my own code if I was often going too far with small methods. I felt the results worked well, but its often hard to communicate the benefits with others who haven’t given it a try.
I found this part particularly interesting:
“Perhaps you think this is taking things too far. I used to think so too. But after programming for over 40+ years, I’m beginning to come to the conclusion that this level of extraction is not taking things too far at all. In fact, to me, it looks just about right.”
For those you disagree with the approach, I would be curious to hear whether you had actual negative results with a project of decent size? Again, notice that Uncle Bob also used to think it was excessive, but changed his mind after using it for a while… Just something to think about.
I wanted to post more here: http://chrismelinn.wordpress.com/2009/09/14/extract-method-how-much-is-too-much/
Thanks again!
@Chris Melinn
No, so far my problems are twofold: a) Methods that are too large and mungified b) Methods that are split badly (chronologically, etc)
I find the Table Of Contents method to work pretty well.
Extract method seems to be the simplest refactoring to think of and the most benfical one – people who use it say it let them reclaim their code :). Yet because you need good names for your methods as well as to organize them in the source wisely it becomes more tricky for some people, escpecially those whose native language is not English – so it’s sometimes costs more effort. If decomposed code is to be more readable for a new programmer naming and organization is critical. You NEED to take a potential reader perspective. It’s not emphasised enough in my opinion.
And here I thought Tomas Malmsten was a loon and had misread Bob’s book. Now I’m not so sure.
I’ll disregard the high cost of doing “contains”-tests on a list. That’s easily corrected. What I cannot let slide is the “stringToReplace” clearly a temporary variable spilled over into a field to satisfy Bobs unquenchable thirst for splitting methods into atoms.
Without seeing the usage It’s hard to tell for sure, but it looks like the “alreadyReplaced” list is a moronic cache to cover for the fact that the symbolPattern matcher is still happilly working on the original string, while String.replace is a hammer which replaces everything in one blow. It is never needed or used for anything else, which means that all of this nasty state can fit neatly into a static utility method if not for the authors perversions.
if (shouldReplaceSymbol(symbolName)) replaceSymbol(symbolName);
Is probably a fun read for a non programmer but it’s pointless filler.
Kudos to you for programming for 40+ years. Have you considered when It’s time to stop?
@Tomek
It is certainly emphasized in the first few chapters of the Clean Code book.
I agree that extracting smaller private methods helps with readability at varying levels of abstraction (at least, personally I prefer this, rather than having to deal with looping contructs or nested if’s when I want to quickly know what a method deals with). Additional advantages include reduced duplication, and quick identification of opportunities to apply other refactorings like Move Method, Extract Class, etc.
I’d also like to highlight that the inverse refactoring of Inline Method is almost as important. That is helpful again as one goes about refactoring code.
I disagree with some comments on this post that suggest documentation or inline comments as a better alternative to extracting methods. In my experience, comments quickly begin to lie (get outdated or be totally wrong because of a copy/paste + code modification): http://c2.com/cgi/wiki?CommentCostsAndBenefits
As far as the code example of this post goes: it makes me uncomfortable that the field stringToReplace is modified in place by the public methods. These can easily lead to unexpected/uncontrolled changes as someone else pointed out (by repeated calls to replace()). In my experience, “verb classes” are best immutable. I still prefer injecting the string to operate upon in the constructor and kept as a field (just final) over being passed as an argument to a static method. The problem with the latter is that when you extract smaller methods, the original argument will need to be passed around too as those new methods will have to be static too and can’t refer a field.
Personally I would prefer an approach such as this:
It avoids mutable state making it thread safe and allows reuse of the same instance for many strings. It also allows injection of the symbol dictionary for testing, and using the matchers built-in functionality for replacements to avoid the replacement mis-features that have been highlighted above :)
@Angry Man your tone is disrespectful. While you may or may not have a valid point, your point is lost in your vitriol and disrespect.
Everything can be overdone. While I agree that simple expressions are better than complex ones, that shorter statements are more readable than longer ones, and that short methods are more readable than long ones, the old addage of “everything in moderation” still holds true.
Let one method do one thing, sure. But let that one thing be specified at the correct level of abstraction. Do one thing in the problem domain, even though that one thing may be divided into a handfull of statements at the implementation level.
The first piece of code on this page is to me the simplest and most readable by a clear margin, even though Henrik Gustafssons implementation is better.
“A shorter class with fewer methods is better than a long class with many methods” might be the missing rule in Bob’s strategy. The ideal is not to have all methods containing only one statement. Natural language programming has pretty much failed because natural language is ill equipped to provide the unambiguity required by computers. I question the need to emulate it in Java by maximizing the number of verbosely named methods.
Splitting everything into tiny fragments creates wonderfully succinct methods which are easilly understood, but the big picture of what replace() or even the entire class tries to accomplish is obfuscated.
@Sam for you convenience I’ve placed any disrespectful comments at the end: It’s not vitriol, it’s bile. A direct result of the gastrointestinal discomfort provoked by Bob’s code. It is more vile to me than any words I can think of.
As many have noticed, this sort of “extraction” makes the complete code harder to follow. Just look at the difference between the original code and the final one. The final code is a lot messier, as if Java wasn’t verbose enough as it is.
What is particularly bad in this post is the fact that Bob Martin doesn’t even try to justify this kind of approach by arguing how it benefits the programmer. He’s “splitting functions for the sake of following a rule”, as Aaron pointed out. Perhaps all that butchering improves readability for non programmers, but really, can anyone imagine working with an API that splits every single abstract idea you want to code into 5 times as many functions as necessary? Abstraction goes down the drain with such an approach, and saying “I’ve been programming for 40 years, I know what I’m doing” is no substitute for rational argument.
I think Angry Man really nailed this down. I quote: “A shorter class with fewer methods is better than a long class with many methods”. Maybe they should come up with some easily digestible “principle” (which are not really principles, but guidelines) to take that fact into account.
In my experience, if a class needs to do complex internal work, it should have a set of private/protected functions. Those functions, however, should be split into logical units within the highest possible level of abstraction. That makes them easy to understand and work with. It makes things as complex as they have to be, but no more. What Martin seems to be advocating is the complete opposite.
IMO, extracting methods to the depth that Uncle Bob describes doesn’t hurt the follow-ability of the code. As a developer, we owe it to ourselves to make our lives easier. Extracting methods allows us to think at a level of abstraction that is appropriate to the level of the method.
We’re cutting out the low level details and putting them where they belong: a concise method that is easy to refer to if we need that level of detail.
@Sam you can ignore this one altogether.
@Stacy well you’re a moron. And so is Unclebob, and it’s about time he was exposed as the pathetic amateurish fraud he is. Unfortunately he is Emperor among the people who have no business writing code in the first place, of which i suspect you belong. I guess I don’t have to tell you what kind of clothes I believe the Emperor is wearing?
For those who have yet to drink the kool-aid, Take a look at how they are working through http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata in http://www.vimeo.com/2499161 It is a sad exercise in misuse of Test driven development.
See if you can comprehend the level of insanity that’s going on there. Take note of Bob’s answer on how he knows he’s done at #9. It at about 6 minutes in.
It’s cargo cult programming masqueraded as philosophy. Insight is claimed but it is false, imagined insight. It is like insight of the paranormal. The strange thing is that when you read Bob’s articles a lot of the time they seem perfectly resonable.
Fun fact: Bob’s prime factor algorithm performs 2x as many divisions as necessary.
Every class has at least two DSLs (Domain Specific Languages) going on:
1. What I am Trying To Do Here, (the “What” DSL)
2. How I Have Implemented That (the “How” DSL)
To me, the main reason to learn to “extract till you drop” is that we need to keep those DSLs separate. What you are “dropping” is the conflation of those 2 DSLs.
The “How” DSL is all about the tips, tricks, and workarounds of the language in question. Matchers and StringBuilders an whatnot. That’s important, but less important than the “What” DSL.
This is because, when it is time to extend or maintain SymbolReplacer, it is the local semantics of the “What” DSL that usually is being changed. We need to get a handle on “What” the class is doing quickly, before we dive into the “How.”
The nextSymbol() extraction, for example, makes replaceAllSymbols() more expressive, not less. It hides silly Java implementation cruft behind a locally-useful, extensible new noun. It pushes a bit more “How” away, refining the “What” a bit more.
Personally, I will gladly pay the tax of a few more methods, in exchange for quickly being able to wrap my head around that “What” DSL quickly.
Uncle Bob is right. Extract till you drop. Extract till your drop every bit of coupling between your “What” DSL and your “How” DSL.
@PatrickWelsh you’ve split the how into grains of sand. Replace whatever grain you want but what you’ve actually done is semented the algorithm into stone.
You have defined the algorithm explicitly, not only in the written code, but in the nouns of the methods and how they call each other. You have done the exact opposite of what you claim to.
It is impossible to change the how without pretty much changing every method below the one you are working on, because that is the only way of making a change that actually changes anything at all.
The thinly sliced “hows “are reduced to the point that they cannot be anything else and still be part of the same context, and still they depend on class fields providing state making the whole exercise even more pointless.
Buck nekkid I tell you. Buck nekkid.
@Angrier Man You actually have a point. Lots of tiny methods may be make code readable, but they definitely make changes harder.
Good. Perhaps you are now ready to drop all side effects and go fully functional? After all, the benefits of that have been mathematically demonstrated a long time ago.
Forgive me for seeming to go off on a tangent for a short while (all will become clear soon)...
The way we structure code is directly related to how we structure solutions within the mind. Psychologists model memory as a network of chunks (a chunk is defined as “memory elements that have strong associations with each other but weak associations with elements in other chunks”). Each node on the network has an image associated with it, this can be a word, a visual image etc. (anyone familiar with mind maps will recognise this structure). This is detailed more in the paper I presented at OOPSLA this year (apologies for the shameless self promotion), see http://www.chunkinganalogies.com for the presentation (with script) and the paper.
When we write code, we group together elements that are strongly associated (the cohesion/coupling principle). Functions & methods are a way of grouping such elements and providing an image (method name). Saying that a function should do one thing is the same as identifying it as a chunk. However, using the indirection of a function has time and capacity penalties for our limited cognitive process (see the section “Code for Experts and Novices” in the paper). We can use statement structure and comments to identify chunks and provide images rather than revert to formal functions (and the associated indirection cost). I would envisage that each person’s view of the most appropriate level of extraction is different and probably primarily dependent upon programming expertise.
Tom
The best for me are 1st, 2nd and maybe 3rd iterations. The last is by far too divided and complex to understand by human. Usability and simplicity is much more important in that piece of code
Living without an aim is like sailing without a compass. with a new http://www.handbags4buy.com/ idea is a crank until the idea succeeds.
Very quietly I take my leave.To seek a dream in http://www.edhardy-buy.com/ starlight.
Maybe we can make this certain with more accurate prediction system. There are many references to work this out.
thank you for sharing the post ,it is really good PDF to BMP Converter is the
excellent combination of super high conversion speed and perfect output quality. At the same time, PDF to BMP Converter supports
various output formats like: JPEG, TIFF, TGA, RLE, EMF, WMF and so on. dhdh
I think Angry Man really nailed this down. I quote: “A shorter class with fewer methods is better than a long class with many methods”. Maybe they should come up with some easily digestible “principle” (which are not really principles, but guidelines) to take that fact into account.
I like This site! Thank you for your information
Well , the view of the passage is totally correct ,your details is really reasonable and you guy give us valuable informative post, I totally agree the standpoint of upstairs .v http://www.hwaterhrim.net I often surfing on this forum when I m free and I find there are so much good information we can learn in this forum!
I think Angry Man really nailed this down
Thank you very much for this blog.I like its.As to me it’s good job.I come to this site then read this article and i will read your next articles.
Guide on how to copy dvd to ipad, how can I copy files onto an ipad, how to copy a dvd movie to ipad, how to copy files from computer to ipad.
I like the 2nd and 3rd iterations best. By the time the last iteration is reached the code feels a lot less compact and succinct. I think that extracting ad nauseum on every method in a class would balloon the size of the class and make it hard to keep all in mind at once.
P.S. It would be interesting to see patch sets with a commit after each change of the full class.cheap VPS
interesting thanks for sharing
(like me) have been telling us that functions should do one thing. They should do
Very interesting post…
that’s quite interesting read
I did some refactoring, but it didn’t work well. Thanks anyway for the ideas.
Avoid getting in a hurry to get a present for ones mom. Start searching ahead of time; waiting until the last second to find a found is often getting problems.Spending some time to learn what an individual’s Mum would like as well as might help guarantee that your gets the top found. If you opt for necklaces regarding Mom online will assist cut down the amount of time necessary to discover the proper jewelry pertaining to mama despite the fact that have waited through to the very end. Therefore when your going looking for mother’s day, on the liner where to begin from.
If the goal is to make development and maintenance easier and fully extracting the class makes it more difficult for a developer to follow the flow of the data is it better to fully extract just for the sake of following a rule. If a class needs to do complex internal work, it should have a set of private/protected functions. Those functions, however, should be split into logical units within the highest possible level of abstraction.
Wide range of web hosting services are accessible, such as cheap vps , email hosting, Unix hosting, forex vps , Windows hosting, Linux web hosting windows vps etc. We hope you will find a cheap hosting company.
iPad video converter for Mac can easily convert the video to Mac video. Keep the high quality.
Texte en PDF Convertisseur est un logiciel qui permet de convertir des fichiers Texte en format PDF. En plus la fonction essentielle-convertir en PDF, Texte en PDF Convertisseur est capable de fusionner des fichiers Texte et puis les convertir, de protéger votre fichier par les mots de passe. Télécharger gratuitement Texte en PDF Convertisseur et expérimenter ce logiciel.
Awesome article!Thank u for sharing!
iPod to iTunes Transfer, transfer iPod to iTunes library, is an all-function transfer for iPod users that supports all versions of iPod and other iPhone devices. It can perform like a transfer, a converter, a ringmaker.
You can free download it and have a try !
In fact, you know. the contacts and SMS have more values than an iphone’s own value. You can spend money to buy a new iPhone, However, if you get your SMS and contacts lost, it is hard to retrieve them. So, you need backup them.
You can free download it and have a try !
such as Rolex Submariner Replica watches includes Rolex Submariner Date Replicas, Rolex Submariner 16610 Replicas
ordered via online stores. The best thing about buying on the internet is you get to see anything the presents, where in a shop it can be tough to sort nevertheless his or her inventory to uncover the right thing. Mothers love gifts that are memorable. Attempt to present your mom using a gift that is persona
If you want to backup your iPhone, because you dare to lose all your information and make your iPhone into a useless element normally if things go off beam, the worst that will happen is that you have to restore your iPhone to its initial pristine state. That means that you’d lose your settings and data on the iPhone. So before you loose your iPhone, make sure you save off your data by doing simple steps.
iPhone to Mac Transfer is a leading iPhone rip, iPhone backup software for Mac users to fast back up photos, songs, videos and so on between iPhone and Mac easily and conveniently.
but that all attempts to improve quality would be short lived and followed by a larger drive to decrease quality even further.
Many people think you’re going too far but I think we owe it to ourselves to set aside our skepticism and give it a real try.
I just wanted to leave a quick comment to say that your blog was nice. I found it on google search after going through a lot of other information that was not really relevant. I thought I would find this much earlier considering how good the information is.
Thank you for this awesome post
my blogs : calories in food | how to put on a condom
Thank you for this nice post
my blogs : how to finger a girl | how to eat a girl out
Good post. This can be a really wonderful weblog which i will definitively arrive back again to additional occasions this year
www.heyheytrade.com Good post. This can be a really wonderful weblog which i will www.lightinthehandbags.com
I totally love this. Thanks for sharing.
eciate contributing generally there, nevertheless are pleased it’s not how you preserve a top above the mind. Some vendors prosper right now there, other folks by no means offer anything. Even essentially the most outstan
Take the latest white iphone 4 Conversion Kit and start to change a new look to your favorite iphone 4 now! You can sure love it!
Good post,I think so! Dear Admin, I thank you for this informative article.
Risk almadan Sermayesiz Evinizden yönetebilece?iniz Kendi i?inizin sahibi olmak istermisiniz ?
It’s a great post. But i would like to know more about the iphone 4 white imformation.
Very nice and professional you taught the whole stuff. I am impressed.
This is precisely what i was searching for. thank you for the informative post and keep up the good work
Intertech Machinery Inc. provides the most precise Plastic Injection Mold and Rubber Molds from Taiwan. With applying excellent unscrewing device in molds, Intertech is also very professional for making flip top Cap Molds in the world.
one day i will back again.
Extract when used multiple times, refactor into a seperate method/class when it’s clearly a different task then the one described by the current context! (usually only in initial versions)
Like other comments, over-extraction makes the code unreadable and unmanageable. I tend to extract parts easily when I think it’s going to be -or is- reused, or is going to be changed and making me or the next developer a little happier (I hope). (reading this text, I might refactor the conditions by using parenthesis and pipes ;-) )
What the hell: if (isDuplication || isCommonCode || isInContext == false) { // Then hopefully making other developers happier. ExtractCodeBlock(); }
Great stuff, worth reading. I really appreciate your post. Thanks for this awesome information.
Every Ugg boot or footwear item is manufactured to meet the highest possible standards. Ugg boot quality is a result of a long history of dedication, workmanship and attention to details. Therefore, any upkeep for the attractiveness and life of Ugg boots is well worth it. welcome to visit our website: http://www.botte-ugg-bottes.com
This topic is really what I’m looking for.
Thanks for share! I agree with you. The artical improve me so much! I will come here frequently. iPhone Contacts Backup For Mac can help you backup iphone contact to mac.
I really like this essay. Thank you for writing it so seriously. I want to recommend it for my friends strongly. iPad to Mac Transfer can help you transfer music, movie, photo, ePub, PDF, Audiobook, Podcast and TV Show from ipad to mac freely.
Just curious.
Perhaps you think this is taking things too far. I used to think so too. But after programming for over 40+ years, I’m beginning to come to the conclusion that this level of extraction is not taking things too far at all.
Thanks for this simple but great code.
Louis Vuitton 2010 http://www.max-handbag.com/louis-vuitton-2010-c-2.html
http://www.max-luxury.com/gucci-secret-medium-hobo-green-223949-p-2274.html”>Gucci secret medium
I love your beautiful heart. I love how you communicate openly, honestly and with much courage what you are walking through. I appreciate you so much!
Earphones not only serve for essential tools to listen to music, but also to show your unique taste. That is why so many young people would like to seek Sony and buy them with quite a high price. Now in headphoneshop.uk.com, we haveSony Headphonesat factory prices, so you just need to invest a little money to take Sony Earphoneshome. when you choosingActive Style HeadphonesYou know what is most important factor in choosing ? Of course, the quality of sounds should be quite essential. active style headphones with perfect technology and workmanship will display the music to the most original level and thus bring you a live feeling?Stereo HeadphonesStereo EarphonesStudio Monitor?These quality active style headphones will reduce the damage to the ear to the least, so love you start from choosing our earphones.
Well, I think it’s pretty clear that each of these functions is doing one thing. I’m not sure how I’d extract anything further from any of them.
Would you like to banckup iphone SMS to mac, macBook, macbookPro as .txt files? Now a software iphone SMS to Mac Backup can help you to realize it.
Louis Vuitton outlet, Hermes bags is are reasonable and affordable.
I was a fashion lecturer at Kingston University and am at the moment doing work on the web site to carry marketplace experts below one particular roof. Thanks for the helpful facts
This is a nice post in an interesting line of content.Thanks for sharing this article, great way of bring this topic to discussion.
You actually did more than her expectations. Many thanks for presenting these effective
JAY Follow laptop accessories the detail tips below, you can increase the laptop battery life of a year or more. 1. The laptop battery first thing you should care about the
Louis Vuitton outlet, Hermes bags is are reasonable and affordable.
Thank you for writing it so seriously.
Buy $10 Replica Designer Sunglasses with 3-day FREE SHIPPING
Thanks for this article.I like its.As to me it’s good job.I wait ur next articles.
Of course the words “It also…” pretty much proves that this function does more than one thing. So we can probably split the function up into two functions
Louis Vuitton outlet, Hermes bags is are reasonable and affordable.
Useful information will I follow your posts. Social Network
A woman is like your shadow—follow her, she flies; fly from her, she follows. True love is like ghosts, which
everybody talks about and few have seen. If men knew all that women think, they’d be twenty times more daring. If a
man wants his wife to pay attention to what he says, he addresses his remarks to another woman. Universities are full
of knowledge; the freshmen bring a little in and the seniors take none away, and knowledge accumulates.
href=”http://www.tiffanyandcooutlet.net/”>cheap tiffany co jewelry
I love your advice “Extract till you just can’t extract any more. Extract till you drop”
I enjoyed reading this article!
I love your advice “I love your advice “Extract till you just can’t extract any more. Extract till you drop”Extract till you just can’t extract any more. Extract till you drop”
I love your advice “oakley glassesExtract till you just can’t extract any more. Extract till you drop”
I love your advice “oakley frogskins Extract till you just can’t extract any more. Extract till you drop”
what’s been said. Robert Martin is ordinarily a fervent promoter of rule quality.I’ve definitely not honestly evaluate or listened to something from Joel – just the pursuing debates much more than his opinions.
Interesting post
Thanks
internette görüntülü olarak okey oyunu oyna, gerçek kisilerle tanis, turnuva heyecanini yasa.
I have some intriguing things preserved for the store. The string may effectively be considered a stark data framework and everywhere it is virtually passed there exists duplication.
I certainly enjoyed reading it, you may be a great author.I will be sure to bookmark your blog and will come back sometime soon. I want to encourage you to continue your great writing, have a nice evening!
I certainly enjoyed reading it, you may be a great author.I will be sure to bookmark your blog and will come back sometime soon. I want to encourage you to continue your great writing, have a nice evening!
Thanks for making such a cool post which is really very well written. I will be referring a lot of friends about this. I hope it stays updated, take care.
Great news update!! I am wondering how you guys manage to find such kind of information so early. Certainly helpful for me and other readers also as I am finding so many good comments here.
Scoop bridesmaid dresses
Can you upload it again?
Great news update!! I am wondering how you guys manage to find such kind of information so early. Certainly helpful for me and other readers also as I am finding so many good comments here.
I am wondering how you guys manage to find such kind of information so early. Certainly helpful for me and other readers also as I am finding so many good comments here.
http://www.vibraminshop.net/Fivefingers-Women-Shoes/Vibram-Fivefingers-Shoes-lilac-classic-shoes_51.htm
GREAT!
Certainly helpful for me and other readers also as I am finding so many good comments here.
Have the christian louboutin patent leather pumps is a happy thing. Here have the most complete kinds of christian louboutin leather platform pumps.
http://www.louboutin-sandales.com/christian-louboutin-escarpin-femme-en-noir-et-bleu-p-183.html ">Christian Louboutin Escarpin Femme est la bonne boutique en ligne
Online UK costume and fashion jewellery shop with, Online UK costume and fashion jewellery shop with, Online UK costume and fashion jewellery shop with,
Contrasted against the grand gowns offered by other couturiers, wonens disel jeans look casual modern even today.Why were these diesel uk jeans considered so shocking? The idea that they look equally chic on men and women. http://www.dieseljeans-sale.net/
Its always an advantage to be able to split the function up into two other programmable sub-functions that actually work and does what it would have simply done in the first place.
mont blanc pens are much loved by people around the world,especially the European,owing to its meticulous style especially the European,owing to its meticulous styleMeisterstuck Le Grandegive attention to both fashion and taste Discount Mont Blanc Pen the best things come when you least expect them to mont blanc pricesMaybe God wants us to meet a few wrong people before meeting the right one so that when we finally meet the person, we will know how to be grateful. It is better bo have love and lost than never to have loved at all. Love me little, love me long. To live in a world without you is more painful than any punishment mont blanc starwalker ballpoint pen enjoy a fine reputation in the whole world Many successful men and women love to have mont blanc pens uk Mont Blanc Meisterstuck pen best quality and surprise price sale in our online store. Meisterstuck Classique Solitaire Ingrid Bergman la Donna is one of the world’s best known international luxury
Do you want to enjoy music and movies so much more with quietcomfort 15 acoustic noise cancelling headphones? Then you have arrived at the perfect place. You may get this product at Amazon for a price much lower than the original quality , you may want to consider using bose headphone bose are considered the pioneers of Noise Cancelling Headphones for Frequent Flyers and Business Travlers, so when they launched their latest offering the cheap bose headphoneswe decided to grab a pair to give you this in-depth review.our online store sell all kinds of styles bose headphones such as ie2 audio headphones bose bluetooth headsetae2 audio headphones bose bluetooth headset ect.if you have interest welcome to our online store bose store babyliss hair straightener babyliss titanium hair straightener babyliss flat iron babyliss hair straightener reviews babyliss mini hair straightener best hair straighteners babyliss pro titanium flat iron babyliss pro flat iron babyliss titanium babyliss pro hair straighteners babyliss pro 230 hair straighteners babyliss mini flat iron ok4sb20110704h
MAC has always been one of the popular makeup brand in the world today. Since the launch in Canada in 1985, they quickly grow by leaps and bounds and become fashion icons. Of course, this has helped many women get the best look, and they desire to have. MAC Cosmetics has a product array. Mac’s flagship products, some including MAC lipstick, MAC Brushes, eye vessels Apple, Mac eyeshadow, eye palette, and many, they are quite popular. Mac products are widely used in the development of many beauty conscious women irresistible. They continue to introduce new product lines and upgrade the color itself.
Thank you for this information. I’ve been looking for something like this for quite a while. Keep up the good work, cheers! klimat thailand lången tips klimat filippinerna teknik blogg
thanks like it
Great post! Nice and informative, I really enjoyed reading it and will certainly share this post with my friends . Read everything you ever wanted to know about promise rings and the meaning of promise rings/a>
a good article! mont blanc pens
e, I really enjoyed reading it and will certainly share this post withhigh quality headphones new design headphones
Thanks for this simple but great code.
thanks for your sharing, It’s very cool!
Although and father’s business empire, DaiLan equate to have is a enviable enterprise. Her Femme Ralph Lauren Polo Chemises network business grows day by day, her shop often hold all kinds of business activities or candy theme party. Her Manhattan flagship store just won alcohol long sleeve femmes ralph lauren polo chemises 3 sales, she was ready to license will decorate afresh for the guest, upstairs to provide the candy theme cocktail, pizza, cake and Homme Ralph Lauren Polo Chemises ice cream. She development of children’s books and to TV program is also very interested.
Perhaps in a home, lauren entrepreneurial spirit is one of the growing experience. This is more of a birthright, than a necessity. DaiLan said: “I always want to do something.” Her brother Homme RL Manches Longues Chemise David, 39, “Swing” (established Swing) magazine and the audience is 20 years old, business for four years. Now that he is in Polo company Hommes Ralph Lauren Sweats responsible for advertising and public relations business. His brother Andrew, 41 years old, operate their own a small film studios. Lauren a often in New York city, new ralph lauren polo chemises long island, Bedford or be toelke Angle have a family gathering, here often become input sessions. DaiLan recalled: “we together around the table, discuss how will each thing in hand to do better, between each other is given the strong support, but also without leave person—but are actively help.”
DaiLan graduated from duke university art major, after leaving school have experienced a procession of the heart that day. She studied acting class, once the audition for MTV show wholesale big pony ralph lauren bags discount anchor, also are eligible for the aerobic fitness coach card, she has run a public relations activities. Then she sink their minds, participate in childhood is never change interest to the color and candy: love. Her father said: Ralph Lauren casquettes “when memories as a child I would like to his office, the sample is put in sugar jar, red and green, and it is very beautiful.” She had assumed that open a candy theme of the gallery or coffee shops, and the club, also want to open a candy museum, then decided to open a candy store.
“The United States style in his hands, from the old values: imagine Femme Ralph Lauren Polo Chemises become real.” This sentence victims Ralph lauren design style and achievement. At the beginning of this century for 40 years of American and British upper social life, the western wilderness, of the old movies, 30 s Femme RL Manches Longues Chemise baseball player and old Volvo is he designed the source of inspiration. In plain style will shekels references to fashion design Homme Ralph Lauren Polo Chemises field, it should be said that his army. Often a lot of people know only POLO (POLO), and do not know its designer Hommes Ralph Lauren Sweats Ralph lauren, actually POLO is just the first of a series of his design for the men’s clothing. At the beginning with “the POLO” as new ralph lauren polo chemises the theme of clothing, because Ralph lauren, believe that the sports let people immediately associate to aristocrat’s leisure. Ralph lauren’s shrewd lies in the world are completely convinced: let the Ralph lauren can buy brand clothing dream, and is worth being. He showed the way a unique style, the Femme Ralph Lauren Hoodies goods of performance is a family atmosphere, this method is very successful, opened in Madison avenue store first years of sales is more than $thirty million. Has been concentrating on shape, wild west, the mind fusion Indian culture, former Hollywood “American style” feelings of Ralph lauren, and finally HOMME RL Manches Longues Chemise even by the magazine media represented the classic “sealed” stylist. “My goal is to finish the design of imagination can be the true and, it must be part of the life form, and become personal. Light circulation at any time” lal
Moncler Jackets http://www.moncler-jackets-factory.com/ Moncler Jackets
Moncler Doudoune http://www.moncler-jackets-factory.com/ Moncler Doudoune
Moncler Outlet http://www.moncler-jackets-factory.com/ Moncler Outlet
Acheter Pas Cher Moncler Online http://www.moncler-jackets-factory.com/ Acheter Pas Cher Moncler Online
Remise Moncler Vestes For Vente http://www.moncler-jackets-factory.com/ Remise Moncler Vestes For Vente
If Abercrombie & Fitch is really concerned that the Situation and company have appeared on air in its garments, it doesn’t appear that angry.Bienvenue pour parcourir Abercrombie France site en ligne, vente en ligne New Style Belstaff en France, vous pouvez acheter la qualite superieure et escompte.Teen apparel retailer Abercrombie & Fitch Co. is offering to pay Michael “The Situation” Sorrentino not to wear its merchandise.Abercrombie Paris est le vêtement de la marque originale et riche d’une histoire enracinee dans le grand air et de la cote Est Ivy League.
nice concept…extract till you drop
Thanks for informative and helpful post, obviously in your blog everything is good.If you post informative comments on blogs there is always the chance that actual humans will click through.
Yeah!
I think your informational post is great resource for lots of peoples, so you promote your blog more by using some internet marketing strategy.
Android developer
Great post! Nice and informative, I really enjoyed reading it and will certainly share this post with my friends . Read everything you ever wanted to know about http://www.addicting2games.com/
wife: XX people engaged, the light bride price of 100 million; your dowry literally two less than the others zero! Also shown with the return of the … ... to now, my family has also been subsidizing. Husband: I was wronged it, how can a good cheap goods? Wife: You … you …!
I agree with you, this can be really anoying. Nice blog by the way, keep up the good work! seo info seo
After reading your post, I thought your thoughts were very naive but as I kept reading on, I do see you have a point. Keep on writing, I will keep on coming by to read your new content.
Don’t stop blogging! It’s nice to read a sane commentary for once.
Life is not always good,but I trust I can do more and more better,day day up,come on.
This is exactly what i was looking for. thank you for the informative post and keep up the good work! Big thanks for the useful info i found on
I admire the valuable information you offer in your articles. I will bookmark your blog and have my children check up here often. I am quite sure they will learn lots of new stuff here than anybody else!
I admire the valuable information you offer in your articles. I will bookmark your blog and have my children check up here often. I am quite sure they will learn lots of new stuff here than anybody else!
Resources like the one you mentioned here will be very useful to me!
I am glad you have posted information on this topic.I hope you will keep this blog up to date with more informatio
You are perfectly correct on that!
It was quite a good read. Good efforts from the webmaster.
WOW!!!!The first impression your blog give to me is so distinctive,very honored to you can share with us your blog. Have a lot of harvest,your masterpiece,thank you very much. In order to thank,I will also give you the way to share a resource Cheap Replica NFL Jerseys. I had visited this Wholesale NFL Jerseys China already,and have gained.Guarantee you will like Womens NFL Jerseys
mastering a terrific deal much more on this matter. If feasible, as you obtain knowledge, would you thoughts updating your web site with a wonderful deal more information? Its very helpful personally.
Slewing bearing called slewing ring bearings, is a comprehensive load to bear a large bearing, can bear large axial, radial load and overturning moment. http://www.1stbearing.com
very nice post, good job
Today the market is flooded with greater variety and headphones
I would like to say that this blog really convinced me, you give me best information! Thanks, very good post.
The new DR-BT140QStereoBluetooth head set with comfortable ear hook design and introduction regarding black,
You make it entertaining and you still manage to keep it smart.
This is truly a great blog thanks for sharing…
In most cases I don’t make comments on blogs, but I want to mention that this post really forced me to do so. Really nice post!
Your posts are extremely helpful and informative.
Function description seem really good and reliable.
great post! thanks a lot! keep it up;)
I wanted to thanks for your time for this wonderful read!! crest printable coupons
I really enjoyed reading this. most efficient space heater
I really enjoyed reading this. most efficient space heater
I really love reading your comments guys.I learn a lot from you.
Thank you so much
Regard,
Epoyjun
The blog is very much interesting with the subject.
The refactored code is absolutely retarded. The first is the best. The second try is acceptable. The rest: fucking garbage.
The blog is very much interesting with the subject.FLOWERS
This is really great i was expecting something like this form you great post keep going.
Hi, all. It is a better idea to backup iPhone content such as contacts, sms and other media files to computer in case they lost by accidently.
Nice post. I will be back to read more of such post keep going.
This article is GREAT it can be EXCELLENT JOB and what a great tool!
I really love reading your comments guys.I learn a lot from you.
Thank you so much
Regard,
Day Traders
how to extract this? will it really work for most of us?
how to extract this? will it really work for most of us?!
One mans “one thing” could mean another man’s fifty things. It is a matter of perspective, but keep in mind perspectives are always changing.
thanks for the share, this is useful links
Australia Beats By Dre Studio dr dre beats headphones beats studio beats pro beats solo hd pro headphones music Official store Monster Beats By Dre Pro
Thanks for the information, I’ll visit the site again to get update information Toys
I must say, i totally agree. This does pose a problem in many circumstances and it is good that something can be done. Unfortunately, it might be a case of too little too late :/ Oh wel..
tribal pants | tribal womens pants | tribal brand clothing | tribal ladies clothing
Thanks!
This really is an awesome post, I’m happy I came across this. I have been trying to find guest writers for my blog so if you ever decide that’s something you are interested in please feel free to contact me.
semi led lights | semi rims | semi chrome accessories | National Seating
Cool, I have not seen one specifically just for navigation to pages alone. Most are for comments or categories. One that uses the new menus feature in 3.0+ so I can make a navigation menu would be exactly what I am looking for. I can not find one and am surprised nobody has created one.
Plumbing accessories | Plumbing parts | Plumbing fittings
Yap Great post! Nice and informative, I really enjoyed reading it and will certainly share this post with my friends . Read everything you ever wanted to know about . http://24addictinggames.com
Intertech Machinery Inc. provides the most precise Plastic Injection Mold and Rubber Molds from Taiwan. With applying excellent unscrewing device in molds,
Intertech is also very professional for making flip top Cap Molds in the world. Mold making is the core business of Intertech (Taiwan). With world level technology, Intertech enjoys a very good reputation for making Injection Mold and Plastic Molds for their worldwide customers.
Intertech Machinery Inc. provides the most precise Plastic Injection Mold and Rubber Molds from Taiwan. With applying excellent unscrewing device in molds,
Intertech is also very professional for making flip top Cap Molds in the world. Mold making is the core business of Intertech (Taiwan). With world level technology, Intertech enjoys a very good reputation for making Injection Mold and Plastic Molds for their worldwide customers.
sadsadsadsa
Wonderlic, Incorporated.implemented ball hats it has the initially audit around 1937. Since then around 130 million possible workers took this kind of examination around just about every marketplace in existence. The exam cheap mlb hats is utilized by employers like a typical assess for considering learning ability and also problem-solving characteristics seen in possible people their offered labourforce.
Lorsque the début du printemps de l’automne et l’hiver de 2011, “les animaux féroces” remplacé avec des fleurs hawaïennes durante pleine floraison au début du printemps 2012, l’ensemble des pulls de repent de pattern enfants, boîte de category chemise à manches courtes aussi aux concepteurs Guess l’ensemble des mains reculent Emotional et aléatoire, durante Guess 2012 série femmes de vacances strenght, l’atmosphère, et l’ensemble des qualités no conventionnelles: pulls tricotés et l’ensemble des robes ze regrouper, “longe l . a . clé dans the collier, fleurs rouge vif à vert olive, l . a . lumière bleue fleur gratuite de affectionate towards…
Durante and de l’impression pattern hawaïen belle Guess série 2012 début vacances de printemps de l . a . femme durante black and white blanc, vert olive, bathrobe encre bleue sera and d’encre consacré dans l . a . mountainous the profil-type robes coupées emprunté depuis l’ensemble des années 1950 pattern de maillot de bain, et donc une combinaison and harmonieuse des sportifs pulls tricotés, durante vrac blanc, veste de fancy dress costume d’olive verte, avec neuf a short time de Bell-fonds, avec n’t spartiates corde durante forme, emotion de détente s’avère être indispensable dans l . a . série de vacances.http://www.guess-fr.com/
michael kors black bag The best way to learn about this would be to visit michael kors tote saleSellBeatsNow.com or click the links in the michael kors bags saleAuthor/Resource Box, otherwise known as the paragraph below… michael kors tote bag Be sure to join the mailing list and if you want to become an expert of Soundclick fast, then be sure to download michael kors satchel handbagthe eBook package as well. Seville is the intoxicating capital of southern Spain, a place of rich michael kors shoulder baghistoric and cultural heritage, where contrasting Roman, Moorish and Christian influences combine to create a michael kors hamilton handbagunique, unforgettable experience for the curious visitor. If you are planning a holiday or weekend break michael kors hamilton large totein the city, be sure to seek out some of the sights below. Barrio Santa Cruz Whitewashed buildings michael kors hamilton bag
With more than 20 years of experience, Intertech provides an extensive integrated operational ability from design to production of molds 100% made in Taiwan. Additional to our own mold making factory, we also cooperate with our team vendors to form a very strong working force in Taiwan.
For the overseas market, we work very closely with local representatives in order to take care of the technical communication and after-sales service to our customers. We also participate in the EUROMOLD & FAKUMA exhibitions and meet our customers every year in Europe. By concentrating on mold “niche markets”, we play a very useful mold maker role from the Far East whenever customers want to develop their new projects. We provide services from A to Z to our customers on a very economic cost and effect basis.
beats by dre headphone vivienne westwood Melissa chirstian louboutin sale michael kors outlet store vivienne westwood handbags
michael kors outlet storeThe newly elected President of Egypt Morsy muhammad published the first speech since his victory over ahmed ShaFei g announced on Sunday night, vowed to “protect the international agreement and obligations”, this seems to be a reference of the peace treaty with Israel..chirstian louboutin outlet
vivienne westwood melissa Morsy tried to appease those worried that he will take immediate action to change the whole Egypt, is expected to become the President all the egyptians, “muslims, christians, old people, children, women and men, farmers, teachers, workers, those engaged in the private and public sectors, the businessmen.”beats by dre headphone
michael kors clearance bags Morsy welcome Obama’s support, the two leaders reaffirm their dedicated to advancing US-Egypt partnership, agreed to maintain close contact with the future of a few weeks, months, according to the statement. Christian Louboutin Daffodile 160mm Pumps
Everybody wants to smell lovely and ebay swarovski the sales of perfume and related birthstone bangle bracelets products are on the increase. The swarovski hello kitty brands can be extremely expensive picture charm bracelets and you will learn how to choose the right perfume here.