I’ve just finished reading Crockford’s book and decided to drop a few lines before I put it back on company bookshelf. In my opinion this is MUST READ for anyone who ever touches any JS code. Especially that JS T.G.P. is actually a very quick read, just a few days of reading if you want to be honest to yourself and grasp all the concepts. Very, very precise book which tells you exactly the things you want to know. In essence – no fluff, just stuff. Another good thing about this book is that it doesn’t say anything about dreaded browsers or DOM manipulation. You devote just a tiny bit of your time and you get rewarded with comforting feeling that you now know all the essentials. I also started googling to check out what people say about Crockford’s idea of encapsulation and information hiding using functions lexical scoping. He even proposes to drop JavaScript pseudo-classical inheritance pattern in favor of functional inheritance pattern to promote information hiding. This is something I personally feel skeptic about. Information hiding is one of the pillars of OO but you need to ask yourself how much you’re willing to pay to get it. In my opinion, when you need to use functions which create functions you sacrifice code verbosity and clarity and that’s a bit too much. My skepticism got even stronger when few days ago I started reading source code for SmartClient – JS library made by Isomorphic. Guys who made this software are pros, no doubt about it. They created their own inheritance mechanism which only supports Crockford’s statement that native JavaScript pseudo-classical inheritance model should not be used. But they use naming conventions instead of real information hiding. If they want property to be private they prefix their names with “_” character and then they pretend it’s private. The same with private methods. Technically you can access it from anywhere , but why? What’s your excuse? You can’t say you didn’t know underscore means private. When I look at SmartClient code written using this convention it looks more natural, more intuitive and easier to read than even small examples which use functional scoping for information hiding. For me that is more important than feeling that my code can’t be tampered with by my team mates or other scripts. Just to sum up, let me make it clear that those facts do not change my overall feeling about the book I’ve just read. If you do JavaScript, even occasionally, you must read it. I think this book is one of top 3 most recommended books on the web. Thank you Douglas Crockford, keep up the good work. Łukasz Kucharski PS. Read English version of the book. Polish translation is simply too much to handle.
<!--:en-->JCE keystore and untrusted sites<!--:-->
Virgo Snaps with Apache Tiles integration
You May Also Like
Testing ServiceMix 4.3 services with PaxExam
- bympr
- March 31, 2011
Toukowi mówcy na nagraniach z Confitury
- byAgata Madaj
- September 19, 2013
Simple trick to DRY your Grails controller
- byTomasz Kalkosiński
- June 5, 2013
Grails controllers are not very DRY. It's easy to find duplicated code fragments in default generated controller. Take a look at code sample below. It is duplicated four times in show, edit, update and delete actions:
class BookController {
def show() {
def bookInstance = Book.get(params.id)
if (!bookInstance) {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'book.label', default: 'Book'), params.id])
redirect(action: "list")
return
}
[bookInstance: bookInstance]
}
} Why is it duplicated?
There is a reason for that duplication, though. If you move this snippet to a method, it can redirect to "list" action, but it can't prevent controller from further execution. After you call redirect, response status changes to 302, but after method exits, controller still runs subsequent code.
Solution
At TouK we've implemented a simple trick to resolve that situation:
- wrap everything with a simple
withStoppingOnRendermethod, - whenever you want to render or redirect AND stop controller execution - throw
EndRenderingException.
We call it Big Return - return from a method and return from a controller at once. Here is how it works:
class BookController {
def show(Long id) {
withStoppingOnRender {
Book bookInstance = Book.get(id)
validateInstanceExists(bookInstance)
[bookInstance: bookInstance]
}
}
protected Object withStoppingOnRender(Closure closure) {
try {
return closure.call()
} catch (EndRenderingException e) {}
}
private void validateInstanceExists(Book instance) {
if (!instance) {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'book.label', default: 'Book'), params.id])
redirect(action: "list")
throw new EndRenderingException()
}
}
}
class EndRenderingException extends RuntimeException {} Example usage
For simple CRUD controllers, you can use this solution and create some BaseController class for your controllers. We use withStoppingOnRender in every controller so code doesn't look like a spaghetti, we follow DRY principle and code is self-documented. Win-win-win! Here is a more complex example:
class DealerController {
@Transactional
def update() {
withStoppingOnRender {
Dealer dealerInstance = Dealer.get(params.id)
validateInstanceExists(dealerInstance)
validateAccountInExternalService(dealerInstance)
checkIfInstanceWasConcurrentlyModified(dealerInstance, params.version)
dealerInstance.properties = params
saveUpdatedInstance(dealerInstance)
redirectToAfterUpdate(dealerInstance)
}
}
}