Tuesday, December 09, 2014

tmux crash course

So you've probably heard about tmux and want to get started.  It might sound intimidating but after you follow this tutorial, you'll find that it's really not that bad.

Here's a basic crash course, written so that you can follow along, step-by-step.

Installation on OS X

brew install tmux

Basic commands

tmux new-session -s foo

Creates a session named foo.

Congrats! You are now attached to a session and you should see one tmux window.

A bit of terminology: you create a session which can have one or more windows, which we'll see below. Within a window, you can split it into panes.

(I'll use ^ to indicate "Ctrl", so ^b means Ctrl+b)

^b c
will create a new window.  You should see a status bar at the bottom of your terminal listing out the current windows. Do it again to create another.

Now you have multiple ways to switch between windows:

^b 1  switches to window 1
^b 2  switches to window 2
^b p  previous window
^b n  next window
^b w  choose window from a list
^b l  (lower case "L") go to last selected window

Next, you probably want to split your current window into panes.
^b "   Split vertically
^b %   Split horizontally

To switch panes:
^b o   Go to the "next" pane
^b up   Go to the pane above. Try left, right, and down as well.

Here's a cool feature of tmux that you might be familiar with if you've ever used screen.  You can detach from a session and reattach at a later time, with all of your windows and panes intact!
^b d .   Detach from current session

Finally, to reattach to a session
tmux attach -t foo   Reattach to a session named foo

Hope you found this to be useful.  Please let me know if you have any questions. Thanks!

Friday, November 14, 2014

TDD: Test behaviors, not methods

What I observed when a developer tests methods instead behavior
One of my favorite books, Growing Object Oriented Software, Guided by Tests by Steve Freeman and Nat Pryce mentions that you should test behavior, not methods. The book, also referred to many as "GOOS", states on page 43:
We do better when we focus on the features that the object under test should provide, each of which may require collaboration with its neighbors and calling more than one of its methods.  We need to know how to use the class to achieve a goal, not how to exercise all the paths through its code.
 When this advice isn't followed
A few years ago, I coached a fellow developer in TDD.  Although I showed how to "write the code you wish you had" and how the tests drive the design, they refused to write the tests first, which is okay -- it was a big improvement from before when there were no tests.

My observations were that the specs described methods, and it was hard to figure out what the class actually did.  Also, one of the core behaviors of the class was never tested!

Another problem was when my team and I wanted to actually use an instance of the class, we couldn't quickly figure out which method, or set of methods, we should call to get the job done.  The specs read like a list of methods, not how an instance actually behaved.

What are your experiences? Do you prefer to test methods, or behavior?

Tuesday, November 11, 2014

Proxy Pattern -- one way out of many towards Clean Architecture


Earlier this year, I bought several of the Clean Coders screencasts, which motivated me to implement a clean architecture in Rails.  It also motivated me to read Uncle Bob's classic text, Agile Software Development: Principles, Practices, and Patterns. I've known about the SOLID principles, but the book really shines once you read past those initial chapters.


For example, here's a great quote from Uncle Bob Martin's PPP, regarding the PROXY pattern:
"It is a way to keep the business rule assets of your project separate from the implementation mechanisms that are currently in vogue." (page 345)
However, this isn't the only way to accomplish this. After reading and understanding the principles in the book, I've found that:
  • By following the D in the SOLID principles (Dependency Inversion Principle), it naturally leads you to design principles such as the PROXY pattern.
  • You have no fear of frameworks polluting your code because the SOLID principles will ensure that the dependencies point in the correct direction
  • Your tests will run extremely fast
  • The only slow tests you have will be integration tests with external resources (database, web services, file system, etc.) and frameworks
  • It's easier to upgrade since you only need to worry about integration failures, not the interaction between business logic and the new framework API. 
If you haven't read the entire book yet, I highly recommend checking it out.  It will change the way you think about writing software forever.

Friday, October 18, 2013

Book Review: iOS 6 Programming Cookbook By Vandad Nahavandipoor, O'Reilly Media

I reviewed this book as part of the O'Reilly blogger program.  

The format of the book consists of concise recipes which state the problem and show how to implement a solution with easy to follow code samples.  I love how the e-book has code samples in color with syntax-highlighting, and I found that the code was easy to translate to use with the Ruby Motion framework.  Of course, the recipes work fine with native Cocoa as well.

Being a cookbook, I don't think this book was intended to be read cover to cover, although I did just that when reviewing it. You could do that as well, but it might serve you better to use it as a reference. The good thing is that this book is organized almost like a non-cookbook; i.e. it has beginner topics in the first chapter(s) and gets progressively more advanced as you go on.

Although iOS 7 is available now, I would still highly recommend this book.
Read more about this book on its product page.

Saturday, October 06, 2012

Book Review: Code Simplicity: The Fundamentals of Software, by Max Kanat-Alexander, O'Reilly Media

Writing code seems like an easy task, and perhaps it is.  However, it can be difficult to write simple, clean code.

The book, "Code Simplicity: The Fundamentals of Software", explains:

  • Why do you want to write simple code?
  • How do you write simple code?
However, you will not find any code samples in this book.  While this may not be appealing to some readers, I did not feel that this lowered the quality of the book.  

It contains many guidelines and principles that experienced software craftsmen already know and might pass on to their apprentices.  Some of these principles:
  • Don't write code that isn't needed
  • Make the code easy to change
  • Comments -- should you add them? Why/why not?
A very experienced crafstman may not get much out of this book, but if you consider yourself a beginner or intermediate software developer, then I'd highly recommend this book.  It's full of great tips that will benefit you immediately and in the future.

You can find more about Code Simplicity on its product page on O'Reilly.

Thursday, March 01, 2012

Review: "The Little Book on CoffeeScript" by Alex MacCaw, O'Reilly Media

This book might be "little", but don't let that mislead you; it's packed with enough content so that you'll understand all of what CoffeeScript has to offer.

Alex MacCaw does a great job of covering the major features of CoffeeScript in six short, but detailed chapters.

He starts off covering the basic syntax, and then moves on to cover something that is frowned upon by many in JavaScript, but not so much in CoffeeScript: classes.  Initially, I was hesitant to use CoffeeScript's classes prior to reading this book, but after seeing how they are implemented, and how easy they are to use, I was sold.

After covering classes in Chapter 2, you'll learn about CoffeeScript idioms in Chapter 3, such as: each, map, select, min/max, etc.  Chapter 4 covers the Cake build system and shows you how to build and deploy CoffeeScript client-side applications, which is pretty awesome.

The book winds down in Chapter 5 talking about what CoffeeScript improved upon in JavaScript, and what it did not. The final chapter is written by the creator of CoffeeScript, Jeremy Ashkenas. It basically talks about the philosophy of CoffeeScript and invites you to create your own special language as well.

My thoughts on the book:
  • It's short and very easy to read.
  • You'll walk away feeling ready to write some CoffeeScript apps or sprinkle it in your Rails apps.
  • The one negative about the book is that in some parts, some syntax was explained after the fact, which made it difficult to understand some of the examples.
  • Overall, I'd highly recommend picking up a copy as it's concise and easy to read.

Friday, February 03, 2012

Book Review: "The Book of CSS 3" by Peter Gasston

Disclaimer: As part of the O'Reilly Blogger Review Program, I chose to review this book.  More details can be found here.


The ideal audience for this book is a web developer who is familiar with CSS and has designed several websites.  In other words, you won't learn how to design a nice layout but you will learn all of the details about CSS 3.

The things I liked about this book are that there are numerous examples in every chapter, with pictures that demonstrate different CSS properties.  Of course, what good is a book about CSS without pictures?
Another thing that you will find useful is at the end of every chapter, Peter provides a chart outlining how well the major browsers support a particular feature.  

There aren't many bad things about this book.  My suggestion is that you do not read it cover to cover, as I believe it would be better used as a reference book.  The only other thing that I didn't like about this book is that the examples are in black & white; it would've been nice to see the images in color, especially in the PDF version of this book.

Overall, it’s a great book to get to learn how to implement the latest cool features in CSS 3.  The numerous examples in the book are very helpful, and it will serve as a great reference book to keep on your desk.

Saturday, April 16, 2011

Replace Prototype with jQuery in Rails 3

Note: I'm using Rails 3.0.3.

I decided to use jQuery instead of Protoype on my personal Rails 3 project.  At first, I naively thought that I could simply include jQuery instead of Prototype, and everything would run just fine.  Instead, I noticed that Chrome was reporting an error in rails.js, which eventually led me to Josh Huckabee's blog post, as well as the official jquery-rails gem.

The installation instructions on the github page are straightforward and simple, so I won't reproduce them here.  After you add the gem to your Gemfile and install it, and you run the command:
rails generate jquery:install
it will pull down the latest version of jQuery.   You should answer "yes" when it asks if you want to overwrite rails.js.

I modified my default layout (application.html.erb) to include this line:
  <%= javascript_include_tag "jquery-1.5.2.min", "jquery.jeditable.mini.js", "rails", "application" %>

Of course, you might not need some of these, and you can include additional files as well.

Friday, December 31, 2010

vim tip: searching for word under cursor

I was motivated to use vim a few years ago, after watching Corey Haines do his number to LCD kata at the Simple Design and Testing Conference (SDTConf). Although I learned the basics while I was in college, I never really tried to progress beyond that until recently.

Now I try to make a habit of whenever I am doing something that just seems like it's the hard way, I'll google it and learn how to do it better.

Today, I was thinking: there has to be a better way to search for things rather than typing "/thing_to_search_for". So I found out how to search for the word under the cursor, which is # for searching backwards, and * for searching forwards.

Hope this helps, and motivates you to keep learning something new everyday.

Thursday, December 23, 2010

Installing ruby 1.9.2 with rvm

I've been having trouble installing ruby 1.9.2 with rvm on Mac OS X.
Although there are lots of great blog posts with solutions, for some reason, none of them worked for me.

The rvm page and many posts say to pass --with-iconv-dir to rvm install.
However, I kept getting errors about Tcl/Tk not being 64-bit, and iconv also not being 64-bit.
Why would it be complaining about iconv, especially since I used rvm to install it?



I noticed the config.log spit this out:

configure: WARNING: unrecognized options: --with-iconv-dir


I tried many options that were in configure, but none of them pointed the makefile to rvm's version of iconv.

So I took a look at /usr/local/lib/libiconv.2.dylib and noticed it was a symlink.
Perhaps this is taking the easy way out, but I backed it up by renaming it, and relinking that to the version inside $rvm_path.
After that, I recompiled by running:

 rvm install 1.9.2 -C --enable-shared


Success!
The output:


Hopefully, this helps some of you out there with similar problems.

Sunday, December 05, 2010

Installing Nokogiri with bundler

I recently decided to start contributing to open source, so I chose to look at one of my favorite Ruby gems, rspec.
The instructions to get you started are fairly straightforward; however, in the rspec-core repository, bundler was failing to install nokogiri.  Although the instructions here worked for some, it didn't work for me.  So based on the instructions on the Nokogiri homepage, I used macports to install libxml2 and libxlst, re-ran rake, and finally, bundler was able to install nokogiri, with no problems.

Friday, October 15, 2010

"Failure of State" by Uncle Bob - SCNA 2010

This is the first of many blog posts to come, with my notes on the talks given at SCNA 2010.

This morning, on the first day, Uncle Bob gave a talk titled "Failure of State." My notes on the talk are below.

SICP - Uncle Bob has mentioned this book many times, and I finally put it on my Kindle today. As a craftsman, you should definitely read this book. It's free but if you can, buy it to support the authors. There are also free lectures available as well.

The substitution model - you can replace function calls repeatedly, ending up with a "silly" version but one that is also stateless and thread-safe. The example given was a program that printed the squares of the first twenty (20) integers.

Many stateful programs exhibit temporal coupling; that is one statement (function/method/etc) must be called before another. In other words, time matters. For example, opening a file, then closing it.

However; in functional programming, y=f(x) no matter when you call it and every time you call it.

Programming has seen three failures so far: 1) the GOTO statement; 2) pointers to functions, and 3) state. Finally, Uncle Bob showed the CQRS pattern, where CRUD is separated into CUD and R.

Tuesday, September 28, 2010

JavaScript documentation

I am doing my part to help others find good JavaScript documentation and tutorials.

Googling "JavaScript tutorial" or "JavaScript documentation" doesn't provide any good links.

The Promote JS campaign aims to change this, so that we all can find better JavaScript documentation, such as the docs here.

Please spread the word! Go to http://promotejs.com/ for more information, and place a link and banner on your blog or homepage.
JavaScript JS Documentation: JS Function length, JavaScript Function length, JS Function .length, JavaScript Function .length

Wednesday, November 18, 2009

Objective-C Object Instantiation

Today we'll go over the syntax to create an instance of a class.

New?
In Java (and C++, to dynamically allocate an instance of a class), you use the new keyword. Objective-C's equivalent is the alloc keyword.
I wish I could say that's the end of the story, but there is a bit more.

Initializers
As in Java and C++, a constructor, and its superclass' constructor, and the superclass' superclass' constructor, and so on, are called in order from superclass to subclass to its subclass, etc.
In Objective-C, constructors are called initializers, and you can consider the init: method to be equivalent to a default initializer; i.e. one that takes no arguments and is supplied by the compiler unless you specify one yourself.

What if you wanted to create initializers that take arguments? By convention, it's recommended to:
  1. begin the initializer name with init
  2. name the initializer to include the word "with"
An example might be on a Person class: initWithGivenName: (NSString*) name
Another convention is that the initializer initializes only the attributes that need to be initialized, and any other values can be set w/setter methods or through other means.

Return type
A"gotcha" compared to C++ and Java: the return type on these initializers have a return type of (id), not the name of the current class.

Designated initializers
Objective-C has the concept of a designated initializer. This is defined as the one that guarantees that all instance variables are initialized. While your subclass does not necessarily have to invoke a designated initializer on its class, it eventually must call a superclass' designated initializer. NSObject, the superclass of all classes, which is similar to Object in Java, contains a designated initializer called simply, init:.

What to return in an initalizer
An initializer either returns "self" which is like "this" in Java and C++, upon successful initialization, or nil if a failure occured.

Ok, so how do I put this all together?
Although you could make two separate calls and "throw away" the value of alloc, it's not recommended. The convention is to chain the calls together on one line like this:

SomeClass *pointerToSomeClass = [[ SomeClass alloc] init];

Saturday, September 19, 2009

Agile 2009 summary


I guess it's better late than never, but here's some of the highlights from Agile 2009.

Clean Code Craftsmanship by "Uncle Bob" Martin
This was an excellent talk about software craftsmanship; some of the points that I particularly enjoyed:
  • Plans are useless, but planning is indispensable.
  • In software, cost of change is low, so the later you think about them, the better.
  • No grand redesigns.
  • The only way to go fast... is to go well. Basically, you have to put in quality, which contrary to popular opinion, does not slow you down but in fact allows you to go faster. Code doesn't rot; we make it that way and it's our responsibility to keep the code clean.
  • Green band: Uncle Bob wears a green wristband to remind him to always keep the code clean, and you can get one here.
  • TDD: By following the three laws of TDD, you can always have clean, simple, testable code.
  • Most attendees had short iterations of either one week or 2 weeks. Uncle Bob said that perhaps when he asks again next time, iterations may be even shorter!
Debugging Pair Programming by Matt Wynne
Although I couldn't stay for the entire session, since I had to leave to prepare for another day of Programming with the Stars, I thought the session started out okay by identifying the benefits of pair programming.
  • High truck number: I've never heard of this phrase before this session. Basically it means that when you pair, you are spreading the knowledge so that it's not just one person who's the expert as in most traditional projects. So if that expert were to get hit (god forbid) by a truck, the team would still be okay. So you can have more people hit by trucks, and the team can still function.
  • Free training
  • Instant code reviews
  • Team building: cheaper than going out for paintball, and less painful.
Each table had a large sheet of paper, some sticky notes, markers, and a persona. This persona was basically someone that may or may not have heard of pair programming, and listed their reasons for not adopting it. Our goal was to list the reasons why they may be afraid to adopt pair programming.

My first table was fine since everyone took a sticky and shared their thoughts. Then we were asked to keep one person at the table, and everyone else move to another table. The person remaining was to explain what we talked about and then discuss how to overcome those barriers.

So, at the second table, I think because there were no moderators, each discussion ended up turning into arguments. Also, some participants' views were not being recorded since the sticky notes weren't being used and it seemed like the guy at the table was filtering out comments. It may have been unintentional but it would have been good to get everyone's input.

Originally, I had recorded the audio on my iPhone, and I was going to listen to the whole thing and write down the key points but I think it's unnecessary now since I'd be repeating what everyone else has already written.

To sum it up in a few sentences: basically with integration tests, you end up with a lot of duplication. The tests become slow and brittle, and as we all know, slow tests end up not being run. We want to make sure that in our unit tests that communicate with collaborators, that we are:
  1. mocking out the collaborators
  2. making sure we are sending messages (parameters) that they can actually handle
  3. ensuring that they respond the way we think they do
This is done with collaboration and contract tests.

This is not to say acceptance tests are useless, because they test the entire system from end-to-end. It's that with the right collaboration and contract tests, you do not need to write any integration tests, and therefore, keep your tests DRY.

I was lucky enough to be selected as a participant in Programming with the Stars 2009, and the star I was paired with was James Grenning, the creator of planning poker and an expert at TDD in C and C++, especially in embedded software.

First day
The first day, we were tasked with refactoring existing code. I hadn't programmed in C and C++ in over 5 years, so I had a lot of catching up to do. Thanks to James, I was able to get up to speed in running unit tests, refactoring, etc in Eclipse. We were given only 3 minutes to perform. When you're up there pair programming in front of a live audience, the time really flies!

Day 2
We made it to day 2, where our task was TDD from scratch. It was another exciting day, but both James and I performed on an empty stomach since the competition was far away from lunch. We were given 5 minutes this time.

Day 3
Somehow, we survived day 2 and made it to day 3, where our task was a 6-minute SDD performance. We used FitNesse and CSlim to show the development of a home automation user story. I was amazed at how FitNesse could integrate with so many languages.
It was a close call this day, as we were in the bottom two pairs, but thanks to the audience, we were saved.

Final Day
The final day's assignment was a 6-minute freestyle performance. There was a coin toss to see which team would go second since throughout the competition, it seemed like going first was a disadvantage.

So it would be the team of Gerard Meszaros and Ola Ellnestam, or Grenning/Chien. The non-star partners were called up to call heads or tails. Ola called tails, but during the coin toss, it hit the podium and I called "interference." :)

James and I decided to recap what we did throughout the whole week. Some of the judges liked the idea; others didn't. It was okay; we were only down by 2 points. After the scoring,the audience was asked to vote by writing down their score, from 1 to 10 for each of the pairs. While that was going on, the bonus round was announced: write "Hello Programming with the Stars" to the console using any language, but with the following conditions:
  1. Leave the computer in its current state
  2. Disable the mouse
  3. The star can only type with his left hand, typing only the keys that the left hand normally types. The other partner has to type with his right hand, typing only the letters/keys that the right hand normally types.
While Meszaros/Ellnestam were performing, the audience's votes, averaged and multiplied by three gave Meszaros/Ellnestam an additional lead of three more points.
James and I were thinking of what language to use and decided on C. I had already typed it up and executed it on my personal laptop, using vi and the terminal.

However, when we went up there, I was confused since we wrote it in Eclipse. Although we finally figured out how to run the program, we were a little too late. The other team finished in 1:28; we finished in 2:49.

Although we ended up with second place, I thought the entire competition was a lot of fun. It was great working with James Grenning, and meeting the other stars and competitors, as well the hosts and judges. I learned a lot, and it was an experience that I'll never forget.

Overall summary of Agile 2009
This was my first time attending an Agile conference, and I really enjoyed it. I made a lot of friends, learned a lot of new things, and I'd definitely recommend going to this conference if you've never gone. Hope to see you next year at Agile 2010!

Friday, June 12, 2009

We're back!

Geekyninja is back, after a long hiatus! I'll be blogging both here and at Critical Phase. Check out my new entry regarding Spring MVC 2.5 and all that annotated controller goodness: Fun with Spring MVC 2.5 Annotations.

Friday, December 19, 2008

Easy dependency management with m2eclipse

If you've ever used Maven, or are currently using it, you know that most of the time, it can be a pain to add a new dependency.

So you know how it goes. You need a new JAR; you fire up your browser of choice, go to the central repository and hunt for the jar that you need. You finally find it after digging through all the folders, then open up pom.xml and add the group id, artifact id, optional version number, etc., and finally, run maven to get the new jar.
Easy huh? ;)

With the m2eclipse plugin, (available at http://m2eclipse.sonatype.org/update/), you no longer have to go through that multi-step process.

If you haven't added the update site before, you'll have to add it manually.
1. Go to Help -> Software Updates -> Find and install
2. Choose the "Search for new features to install" option and click Next
3. Click "New Remote Site..."
4. Enter "m2eclipse" for the name and enter the URL http://m2eclipse.sonatype.org/update/

Now you add dependencies automatically when:
Right clicking on the project and going to Maven -> Add dependency.
and
During coding: code as you normally do, and when Eclipse complains that the class can't be found, you can click on the red "x" and find the dependency by going through the central repository!


In the example below, I added the @RequestMapping annotation to my Spring 2.5 Controller, and since I didn't have the jar in my local repository, Eclipse notified me of the error. (Figure 1)


Clicking on "Search dependency for RequestMapping" then searched the repository, and provided a listing of potential matching jars. Select the one you want and the rest is automatically taken care of! (Figure 2)









Figure 1: Clicking on the red "x" brings up a context menu where you can search the Maven central repository







Figure 2: The class name is automatically entered, and a list of jars that contain that class is shown.

m2eclipse will take care of downloading the required jars and adding them to your classpath. That's it!

Friday, December 12, 2008

SpringOne 2008

I missed The Spring Experience 2007, but was able to return in 2008, and it has been renamed to springOne. During Adrian Colyer's keynote, he posted this hilarious photo:
Yes, that's the Rod Johnson bobblehead doll! I'm so jealous of everyone who was able to attend in 2007. Hopefully they give out something like this in 2009.

On a more serious note, some of the highlights of the conference:

Managing the war on complexity: This was the theme of Rod Johnson's keynote, and I'm glad he explicitly said this, as Spring is truly one of the best solutions to making Java EE web apps simple to maintain and develop.

OSGi: Becoming very popular, and something worth looking into.

Spring MVC: The old Controller hierarchy is going away, and moving towards the annotation based Controllers found in 2.5. Also, Spring 3.0 will have native REST support!

Grails: If you follow the Grails scene, then you know that G2One, the company behind Grails, has been acquired by SpringOne. Rod just reiterated this to let the community know that Grails will have even better Spring support now that they are the same company.

Thursday, July 10, 2008

Grails Eclipse plugin

So I was messing around with Grails the other day, and heard about the wonderful Eclipse plugin. Like the documentation says, grails generates all the necessary files for Eclipse to recognize your project.

This is great and all, but a lot of people I spoke to encountered the same problem I did.
There's a file for your Spring DSL code, called resources.groovy located in
<your-app>/grails-app/conf/spring.

Many people will then receive the following error:

Invalid Package declaration in script: <path-to-your-project>/grails-app/conf/spring/resources.groovy is not in a source folder matching the package declaration: DonutStore/grails-app/conf/spring resources.groovy


I don't know enough Grails at the moment, but a quick fix is to add:

package spring;

to the top of the file.

Update:I've been coding Grails apps for several months now, and realize that this is just an error with the Eclipse plugin. Since I develop on the Mac, I prefer TextMate anyway. However, if you're an Eclipse fan, be glad that the SpringSource guys are working on a new and improved plugin and it should be available later this year.

Tuesday, July 08, 2008

Spring method injection

I recently inherited some legacy code and it's been extremely difficult to refactor. It's a catch-22: you can't refactor without unit tests in place, but it's difficult to unit test since it wasn't written to be testable. [TDD can cure this. :)]

So after much hair-pulling and thought, I was able to extract a few interfaces and configure some of the business logic classes as Spring managed beans. The problem was that some of the dependencies were still being acquired via the "new" keyword, and it had to remain that way.

In other words, I had a singleton bean which required a non-singleton, or prototype. Not just once, at bean creation time, but a new instance every time. How could this be done, without mucking up my code with the Spring API? We definitely do not want a reference to a BeanFactory or ApplicationContext in our bean.

Enter one of the rarer forms of dependency injection: Method Injection (see section 3.3.8).

The recipe is:
  1. Create a method for the dependency and either make it protected abstract, or public.
  2. In your applicationContext.xml, instead of specifying <property name="someProperty">, you use
    <lookup-method name="theMethodWhichReturnsYourPrototype" bean="idOfPrototypeBean"/>


Let's look at an example:

We have a class Homer, which wants a new instance of another bean, a Donut, every time, instead of reusing the same Donut over and over again.


Now, for the applicationContext.xml:

<!-- a stateful bean deployed as a prototype (non-singleton) -->
<bean id="donut" class="demo.DonutImpl" scope="prototype">
<!-- inject dependencies here as required -->
</bean>

<!-- homer (singleton) uses donut (prototype) -->
<bean id="homer" class="demo.Homer">
<lookup-method name="getDonut" bean="donut"/>
</bean>



So what's going on here? To quote the Spring docs:
The Spring Framework implements this method injection by dynamically generating a subclass overriding the method, using bytecode generation via the CGLIB library.


So when Homer asks for a donut via getDonut(), the subclassed Homer, generated via CGLIB, will return a new instance of Donut, which has its dependencies injected by Spring.

Pros of this approach: we are decoupled from BeanFactory and the Spring API
Cons: making the bean abstract makes testing a little difficult, since you have to subclass the class, however, making it concrete and implementing the getter method, you avoid this.