Wednesday, January 31, 2007

Dynamic Language User Group Is Back!

The holidays are over and it's time to get back to programming in the languages we love. I'm happy to announce we have a new location this month courtesy of Matt Payne. It's located at UNO's Peter Kiewit Institute (PKI) building! So, why the change you dare ask? Here's the blurb:
Room PKI 269 is nice because it has about 25 machines, each connected to the Internet, and a large screen projector at the front of the room. A laptop may be connected to the projector or you can just use the PC at the front of the room. Almost every room in PKI has a large screen projector at the front of the room with a PC and a laptop connection. All of the rooms have white boards.

WOW! I would like to give extra special thanks to Heather Blockovich of Tek Systems for all of her help. So, when are we meeting at our bright new shiny place? February 6 is the date usual time of 7-9pm. Of course, I'm always up for a little chit chat before.

Now, for the most important announcement (drum roll please): the speaker! Ben Heath will be providing a special evening of discussion on Common Lisp and his Netflix project. Ben is a passionate programmer with years of experience and is a Lisp and dynamic language lover. It's going to be an exciting talk for sure! I can't wait.

And if that wasn't all, Tek Systems will be joining us with food, refreshments, and maybe a few suprises! Yes, we have sponsorship for this meeting. Now, I have to ask what better way to spend an evening with free food, great place, great people, and awesome Lisp coding?! It's just too good! I look forward to seeing everyone.





TopicLisp and Netflix
SpeakerBen Heath
TimeFebruary 6, 7-9pm
LocationUNO's Peter Kiewit Institute (PKI) building
1110 South 67th Street
Omaha, NE

Sunday, January 28, 2007

Some Self Philosophy

From the Self 4.1 Programmer's Reference, Chapter 4, A Guide to Programming Style:
In short, to maximize the opportunities for code reuse, the programmer should:
  • avoid reflection when possible,
  • avoid depending on object identity except as a hint, and
  • use mirrors to make reflection explicit when it is necessary.

This is the summary to a portion of the chapter entitled, "Behaviorism versus Reflection". It's best explained in this three paragraphs:
One of the central principles of SELF is that an object is completely defined by its behavior: that is, how it responds to messages. This idea, which is sometimes called behaviorism, allows one object to be substituted for another without ill effect—provided, of course, that the new object’s behavior is similar enough to the old object’s behavior. For example, a program that plots points in a plane should not care whether the points being plotted are represented internally in cartesian or polar coordinates as long as their external behavior is the same. Another example arises in program animation. One way to animate a sorting algorithm is to replace the collection being sorted with an object that behaves like the original collection but, as a side effect, updates a picture of itself on the screen each time two elements are swapped. behaviorism makes it easier to extend and reuse programs, perhaps even in ways that were not anticipated by the program’s author.

It is possible, however, to write non-behavioral programs in SELF. For example, a program that examines and manipulates the slots of an object directly, rather than via messages, is not behavioral since it is sensitive to the internal representation of the object. Such programs are called reflective, because they are reflecting on the objects and using them as data, rather than using the objects to represent something else in the world. Reflection is used to talk about an object rather that talking to it. In SELF, this is done with objects called mirrors. There are times when reflection is unavoidable. For example, the SELF programming environment is reflective, since its purpose is to let the programmer examine the structure of objects, an inherently reflective activity. Whenever possible, however, reflective techniques should be avoided as a matter of style, since a reflective program may fail if the internal structure of its objects changes. This places constraints on the situations in which the reflective program can be reused, limiting opportunities for reuse and making program evolution more difficult. Furthermore, reflective programs are not as amenable to automatic analysis tools such as application extractors or type inferencers.

Programs that depend on object identity are also reflective, although this may not be entirely obvious. For example, a program that tests to see if an object is identical to the object true may not behave as expected if the system is later extended to include fuzzy logic objects. Thus, like reflection, it is best to avoid using object identity. One exception to this guideline is worth mentioning. When testing to see if two collections are equal, observing that the collections are actually the same object can save a tedious element-by-element comparison. This trick is used in several places in the SELF world. Note, however, that object identity is used only as a hint; the correct result will still be computed, albeit more slowly, if the collections are equal but not identical.

Basically, the above is basically placing more value on "duck typing" (the new word for behaviorism) than reflection. I've always placed myself in the "behaviorist" camp and anyone that knows me rolls their eyes when I rip into my "@#$%^& not another data structures and controllers architecture!" It's because I place more value on the behavior than I do the data. It has a lot to do with my mentors enlightening me to the teachings of the brilliant Rebecca Wirfs-Brock (yes, she is still my hero).

Sorry for my digression, but why did I quote all of this? First off, I always thought of duck typing and reflection as tools in my bag. I have never thought about why I would pick one over the other. I do tend to pick non-reflective solutions where I can (It seems Joshua Bloch does the same from his Effective Java book as well). The reason being that most people understand behavior, but reflection is not so obvious.

OK, enough background, and on to my real point. This all got me thinking about why I've always been squeamish with reflective GUI, persistence, and rule engine frameworks. Now, before I begin, I love my OO-relational mapping tools and rules engines, but somehow they have always seemed like they were breaking encapsulation. And in fact, they are for great benefit (which outweighs the encapsulation violations). They are going underneath the covers of your objects and exposing them to a privileged few. Now, this gives us great power and takes a lot of things out of our hands. These frameworks do a lot of heavy lifting and breaking encapsulation has always seemed like a small price to pay. But, how could we do it without reflection? Ah, there's an interesting question, no?

Is this mental aerobics going to get us anywhere? I don't know. But, I bet the journey will be fun. So, what do we have in our arsenal right now? Well, off hand you can name the Memento pattern and we could have a simple hash table object that we get values in and out of the object. This could work for all of the frameworks I listed. But, it seems cumbersome and still prone to major changes in the object topology. We're still depending on data, just putting a common interface on an object. Perhaps, this is the point of "Mirrors" in Self is to provide this type of functionality, albeit consistently. It's also slow because we have to keep taking snapshots if we want to track changes (which means we have to ask for the data and then do compares). But, we could use the Observer pattern and trigger events on any change to an object at the end of some change transaction.

Another tool can be found in Allen Holub'sexcellent article about alternatives to getters/setters in GUIs using the Builder pattern. Now, the solution is very specific, but it's a turn on the Memento pattern. I like that fact that it's more about behavior where I have to send an object that understands the messages and reacts to those messages instead of being passive. But, it still seems the Memento pattern wins because it can be more generic (at its simplest: get(key) and put(key, value)).

I'll leave this article as a point to ponder. There might not be an answer. But, I think a pure behavior approach is more understandable and simple than a reflective one. If anyone has any thoughts, please send them to me. I'll post any further thoughts as I have them. I'm always thinking of ways to preserve encapsulation in my designs. Just remember, Alan Kay wished he had called object-oriented programming, "message-oriented programming". It enforces the black box nature of objects and strong communication semantics. It keeps designs simple and easily reasoned about. Now, don't get me wrong, I don't hate reflection. I just feel like we should always seek alternatives, like inheritance it holds awesome power. But, in the wrong context can cause maintenance issues. Just because you have a tool doesn't mean you have to use it. Besides, forcing constraints on yourself, can cause interesting thoughts on your future designs.

Saturday, January 27, 2007

Smaller Is Better

"The smaller the object, the more forgiving we can be when it misbehaves." -John Maeda, "The Laws of Simplicity"

This quote was talking about real world objects, but I think it's doubly true for software objects. If we keep our objects small in our design (single responsbility), we will be more forgiving when errors arise. Why? Small objects are easy to test, debug, and well, fix. In fact, the fix is obvious because the object is so small. It's time to make our objects small and build layers of domain specific languages on top where each layer is simple to comprehend and understand. It would make our designs "more forgiving" to the ones who have to maintain it.

Magnetic Fields Metaphor

Got this cool Alan Kay note:
Magnetic Fields:
Find a central metaphor that's so good that everything aligns to it. Design meetings are no longer necessary, it designs itself. The metaphor should be crisp and fun.

Metaphors are a hotly debated topic in XP/Agile circles and I've never understood why. Alan Kay's quote resonates with me because when you have a good metaphor for your system, you can easily make design decisions as they arise. It keeps your design cohesive and simple. Of course, if your metaphor doesn't fit, it can have the opposite effect. I don't force metaphors, but when one pops that fits...I grab it whole-heartedly. But, I will take the time to brainstorm for one. The metaphor should be your compass that helps you navigate through your design decisions.

Language Of The Year

Following the tradition after reading "The Pragmatic Programmer" to have a new language to learn every year, I have decided to learn Self. I have spent loads of time reading every article and book I can on prototype-based programming. As well as playing around with languages like Io, Slate, and even Javascript, but I always wanted to play with the real thing. Now, that I have a Mac, I can finally get to do that. This is going to be so much fun!

Sunday, January 21, 2007

Feed Change

When blogger.com updated their software, it stopped updating my blog feed for some odd reason. So, my feed URL has changed to: http://blog.blainebuxton.com/atom.xml. Please update your readers and I apologize for any inconvenience it might have caused. Thanks for reading!

I did make a few changes to where index.rdf will now still be updated from atom.xml in the meantime. Again, thanks for everyone's patience on this matter.

Wednesday, January 17, 2007

Java And Simplicity

I was reading 10 Reasons Why Java is Drifting Away because I'm always curious to what other people think of the changes in Java. And I came across this comment:
I believe, simplicity of language is VERY UNDERESTIMATED asset.

See, I worked for years with c++. I liked templates, they were
giving me a 'mental satisfaction'. I liked to check generated
assembler, emmited own instructions when not satisfied.

But that's not way how programs should be made.
Once switched to java, I apprecitated simplicity of java.
Java followed KISS principle, provided simple language,
simple tools (javac, javadoc, javah ... ).

Now, we are loosing this important asset.
Converted c++ programmers ask their templates and operators.
Converted c# programmers ask their properties and closures.
Coverted script programmers want their dose of language sugar.

Java creators made java simple - and not simpler then it should be.
We should apprecitate and preserve it (in rational way).

OK, I'm sure that some of the Smalltalkers and Lispers out there either have their jaws on the floor or hurt bellies from laughing so hard. I know I did at first and then it struck me. We have failed. We have failed to educate on what simple can truly be. When I think of simplicity in language design, I think of Self, Smalltalk, Forth, and Scheme. Java wouldn't even come close. But, there's an army of developers out there that haven't seen better and that is sad.

Sure, we could easily laugh at the uneducated, but it's our fault. Instead we should be sharing and telling. I spent time at RubyConf showing off Squeak and have been known to hang out at the local Java user's groups talking all things dynamic. I enjoy showing people the power that's out there and the great thoughts that have preceded us. It's exciting to see Java getting some of these capabilities and programmers demanding them! The future is bright, but there are still some we haven't reached.

Next time, you hear someone call Java simple, don't snicker. Show them something simple. Who knows maybe someday I'll be able to program in Self because it will be the defacto standard. A boy can dream can't he?

Wednesday, January 10, 2007

Favorites Of 2006

Every year I like to do my favorites of the year. I normally post it on one of the music boards I'm on. But, it's fun to read previous years' lists. This year was simply incredible. I love a lot of different genres and I was overwhelmed. So, without further ado, my favorites of 2006:
  1. Unexpect-In a Flesh Aquarium
  2. Muse-Black Holes And Revelations
  3. Into Eternity-Scattering Of Ashes
  4. Pure Reason Revolution-The Dark Third
  5. Peeping Tom-Peeping Tom
  6. Axamenta-Ever-Arch-I-Tech-Ture
  7. Hammers Of Misfortune-The Locust Years
  8. Die Apokalyptischen Reiter - Riders On The Storm
  9. OSI-Free
  10. Ghoul-Splatterthrash
  11. Frost*-Milliontown
  12. AFI-December Underground
  13. Strapping Young Lad-New Black
  14. Mars Volta-Amputechture
  15. Dragonforce-Inhuman Rampage
  16. Estradasphere-Palace of Mirrors
  17. Cradle of Filth-Thornography
  18. Black Stone Cherry-Black Stone Cherry
  19. Trivium-The Crusade
  20. The Faceless-Akeldama

Tuesday, January 09, 2007

Zero Mass Design

First off, if anyone can get me a copy of Dave Thornburg's "Zero Mass Design", please send me an email as soon as possible. I was reading "Programmers At Work" again and this time I reading the interview with Scott Kim. And this was interesting to me:
He has a little book called "Zero Mass Design", the premise of which is that if you're going to work on something - for instance, you're going to write a book, or you want to write some software, or you are about to embark on any project that requires planning -- start with a simple design. But it's more extreme than just keeping it simple; you start with a design so simple that it won't work. That requires a great deal of discipline because you go into the project with the premise that you will fail; until you've tried something and actually seen it fail, yoiu don't know how simple you can get.

Does it sound familiar? Sounds sort of agile doesn't it? The explanation that he gives next is the best I've read for "Do The Simplest Thing Possible" mantra of XP. Read on:
Dave Thornburg's example, from James Adams' book "Conceptual Blockbusting", is the Mariner IV spacecraft. It had large solar-cell panels that unfolded. The problem, as stated, was to have a mechanism that slowed down the panels as they unfolded so that they wouldn't break when deployed. So, they tried oil, but that was sort of messy, and they tried springs; they did all sorts of things. The day for the launch was coming nearer and nearer. What were they going to do? Remember, the problem as stated was to find a way to slow down the panels, or to find a braking mechanism. Finally, somebody had the brilliant idea to try it with nothing, so they tried it and the panels shook and shivered but nothing broke. If you state the problem with assumptions, you're going to get them. You're got to pare back and pare back and pare back. Starting with a very simple design has wonderful advantages, but it requires a pyschological twist; you have to expect that it will fail and enjoy that.

I like to get requirements stated in goals which is a trick I learned from use cases. Get the problem stated as a goal and a lot of assumptions can be removed. You'd be surprised how well it helps. The point is not only to "Do The Simplest Possible Thing That Will Work", but state the problem as "Simply As Possible". It removes assumptions and thus, doesn't color your design with needless complexity. Those words slapped me in the face and it seemed everything came together. Wow.

How To Make Sure Your Fans Don't Find You

Change your name for American audiences. One of my favorite bands for a long time has been Die Apokalyptischen Reiter. Imagine my shock and surprise when I saw that they had a new album out called "Riders on the Storm". Imagine how delighted I was that it was excellent. Imagine my dismay when I found out that it wasn't their first album in 6, but 3! What?! They had an album come out in between which I guess they tried to rename themselves only for American audiences. On this album and only in America, they were called "The Apocalyptic Riders". Huh? I've been a fan since their first album and I think it's funny I missed this album because of it. Of course, Die Apokalyptischen Reiter is German for
"Riders of Apocalypse". Why the name change? Oh well, who cares? One of my favorite bands are back and I got two new albums by them this year. I should be happy and I am! I just would have liked to been listening to one of them now for 3 years....I got a lot of time to make up!

Great Post On Smalltalk and Parsers

Gilad Brocha has a blog and he made great post recently on Parser Combinators in Smalltalk. It's a great read with lots of funny quotes:
tangent: No Virginia, Smalltalk does not have operator overloading. It simply allows method names using non-alphanumeric characters. These are always infix and all have the same fixed precedence. How can it be so simple? It’s called minimalism, and it’s not for everyone. Like Mies van der Rohe vs. Rococo.

He makes more and it's a great read. I almost got diet pepsi all over my new Mac while reading it. I tend to stand on the same fence that thinks functional and object-oriented programming compliment each other well. I'll even go as far and say they need each other. I ran across this blog because of my recent interest in Self and Factor. Fun stuff!

Monday, January 08, 2007

Don't You Want To Own a Lisp?

If you want to read something funny, go and read Volkswagen Lisp. I was laughing the entire post. I'm amazed at how many different uses and what people had turned their Bugs into! Cool post.

Sunday, January 07, 2007

The First Week With Mac

I've had my Mac for a little over a week now and I'm feeling comfortable with it. I like how the most common defaults are just selected for you and it seems a lot of thought has been put into the interface. For example, usually there are no OK buttons on dialogs and it generally selects the right default for you. The screens are just simply gorgeous!

I love the quickness of putting it to sleep! Wow! Booting it up from scratch is slow, but I've only had to do that once so far. I just put it to sleep. Nice.

I'm enjoying Dashboard and I've already gone a little nuts with it. I think I have something like 8 widgets. I have a weather one, two quotes of the day, inspiration for the day, word of the day, unix command lookup, ruby documentation, and a thesaurus.

Switching between applications is nice. It took me a little time to get into the multiple windows per application way of thought. In Windows, everything is a window with no grouping by application. Mac groups windows by applications and makes it super easy to switch between.

The only problem I've had is re-learning key mappings for Eclipse and Squeak. They are generally the same, but it's the apple key versus alt key on Windows. The keyboard is a laid out a little differently too, but I'm not complaining. It's just taking a little to get used to.

I'm loving Self. It makes the whole reason for getting the Mac worthwhile. I've been going through the tutorials and I've only scratched the surface. But, language-wise I'm so impressed with Self. They take their simplicity seriously!

On more thing, I can now read postscript files directly! Yippee! They get converted automatically to PDF and that is wonderful. I can see I'm going to go super crazy with academic papers. Mac will be my pipe for my crack.

My Mac didn't come with an AirPort card and the battery lasts 1 minutes. I'm missing my wireless and I got to have battery power. All in all, I'm having fun with it. Right now, I'll be staying in both Windows and Mac. But, there's a lot of cool things on the Mac that I still need to explore like XCode. I'll keep you posted!

Theme Song For The Year

This year my wife, Michelle, came up with the great idea to pick a theme song for the year instead of make new year's resolutions. Basically, pick something that will inspire you for the whole year; something that will frame the year for you. I started out going through my collection and wanted some anthemic. I finally decided on Jean-Michel Jarre's "Rendevous IV". I've been a fan of Jarre for quite sometime and I always seem to listen to "Rendevous" when I've been triumphant or want to be. The music is catchy and it inspires me every time I hear it. I have a collection of music that I've always played before contests and interviews and this one is the last one I play now. I also picked this one because of the grand visions that I have when I hear it. I guess that comes from the first time I heard it was on Jarre's Moscow DVD and the imagery was awe inspiring! Needless to say, I expect 2007 to be a GREAT year! And yeah, Jarre RULES!

One Way

I was reading "Programmers At Work" this morning while giving platelets and ran across this quote from Jef Raskin:
Most computer designers, for some reason, delight in providing many ways of doing something. If there are fifteen ways to do something, they think it gives you freedom. The fact is that most users don't use the majority of the commands on their word processors. There are a few that everyone uses. And even though they've read the manual and know it might be a little more efficient to use a special technique, they don't bother. They use the same ones every time.

I've seen this time and time again. I know I've even fallen for the "flexibility" fallacy where I should have been simple. The above can apply to not only user interfaces, but APIs and languages. It made me immediately think of Ruby.

Ruby falls prey to the "flexibility" vulture and it's even touted as one of its greatest strengths by some (Reason #7). You have two ways to define blocks ({}, do), various ways of constructing arrays (new Array, %w), and other things to make various programmers from other languages feel comfortable. I think Ruby itself needs to become more opinionated.

There's a lot of great things about Ruby that I'm proud that are finally getting into mainstream minds like dynamic typing, closures, and meta-programming. It's cool seeing all of the excitement. But, I think if Ruby wants to go further, it needs to trim some of the fat. Now, this fat might have made programmers from other languages more comfortable, but we need to lose it. I would like to see Ruby more lightweight, easier to parse (it's a nightmare), and of course more opinionated. But, I worry that with all of the activity that bad habits will continue. I'm worried about the future of Ruby because all of the forking and lack of a clear direction.

With all of the battles that Ruby has won, I would hate to see it fail because of sins to gain more acceptance. It's won that, now, let's make Ruby the best it can be.

Wednesday, January 03, 2007

More On Nulls

Not to beat a dead horse, but Michael Feather's Offensive Coding article and Steve Riley's How null breaks polymorphism: or the problem with null: part 2 made me want to explain in further detail how I prevent using nulls. I thought they might be some use to other designers. Note, some of these are also discussed by Michael and Steve.

Empty Collections instead of null.

The easiest way to prevent null pointer exceptions when using collections is to use empty ones. The Java collections library in fact includes empty versions of all the collection interfaces. Use them. It takes a little more typing, but it prevents one more check. And usually, most collection code can be written to be size agnostic.


Use meaningful defaults.

This one is really simple. Instead of being lazy, think about good defaults for your objects or at least ones that will be easy to spot when debugging. One of the problems that I have with nulls is that when I have to debug code, they tell me nothing about the intention. A default can give some sort of clue. If defaults can not be used, then...


Throw an exception.

But, if you must insist on using nulls, then please don't use them for incorrect usages of your API. In other words, if I pass you bad parameter, don't return null because your API can't handle it. Signal an exception and tell me what the problem is. Sadly, the Java collection API falls into this trap. The implementation of Map returns a null if it doesn't find the key and null is ambiguous in this case because it can be the key was not found or that null was stored as the value. I think an exception for the first case would prevent that. It would also make it easier to spot an incorrect usage of the API with a good message to tell me what to correct. Good designs are easy to debug and require little to no detective work. Be nice to your users.


Use small objects.

Wrap primitives into something more meaningful. You can then use the interface for both the implementation of real values and another one for true Undefined scenarios. Small objects are easy to debug because they can give much more meaningful information and you don't have to deal with all knowing objects that are 300+ lines of code. Small objects make dealing with nulls easier because...


Null object Pattern.

This pattern described in "Pattern Languages 3" by Bobby Wolfe. Go read it now if you haven't. Basically, implement a different implementation of your interface that either deals with the undefined case more gracefully. Now, by that, I mean, either throw an exception detailing why the request could not be completed, ignore the request, or forward it on to someone else. There could even be more options, but the first two are the most commonly used which of course, brings me to...


Deaf object pattern.

This is the Null object pattern where the implementation of the interface ignores all exceptions. This is used throughout Dolphin Smalltalk to great effect. This is a dangerous pattern, but when used right can make life easier. Dolphin uses it as a placeholder for objects that are not fully instantiated yet and requests would not make sense. It does this external resources where the object is instantiated, but they have not yet allocated the proper resources yet to make it fully functional. It helps them avoid timing issues. Again, I would caution the overzealous use of this pattern because it can mask bugs which brings me to...


Undefined object pattern.

Yet another popular variant of the Null object pattern, this version throws an exception with a meaningful message (be creative, but put something better than "undefined object<>

In closing, the one point I want to make is relying less on null requires thought in your design. Too many times, I see use of nulls as absence of caring for the users of your code. Nulls are just lazy and you can replace most of the them in your code using the above arsenal. Plus, the techniques above can make your code more readable, easier to debug, and more fun to extend.

Amen

I missed another great quote from Arto's blog on Lisp:
I’ve also been reading a lot of the relevant academic literature published since the 1970s; for instance, the Lambda Papers and the myriad works of Henry Baker have been particularly inspiring. I continue to be struck by the harsh reality of the often-asserted, but seldom-accepted, truth that most of the great work in software was indeed done very early on, with virtually no further fundamental progress having been made during the past couple of decades.

I'm in the same boat. I'm just so much in awe of early computer science. I've been reading David Parnas's old papers and they are inspiring. It's amazing how much of the old papers we are reinventing. It's fun and mind blowing reading, but depressing that we haven't push the envelopes further. I think it's time to stop being sad and just do it.

Here's my call to arms. Let's take it further and stop whining! Who's with me?! CHARGE! The next generation of computer science starts NOW!

Superfluous Parentheses

A Lisper talks about The Road to Enlightenment is Littered with Irritating, Superfluous Parentheses or his road to Lisp. It's a great read. He put in several funny quotes like:
of course, I can’t help but admire what the Smalltalkers have built with Squeak. (I suppose once you’ve reached the Source, being a polyglot becomes second nature.)

and...
The Lisp machines seem to have been the apex of Lisp, a brilliant achievement still unequalled (except by the Smalltalkers, as always). These wonderous machines have been followed by two decades of standstill, or even retrograde, progress.

It's funny, but I chose Scheme as well for slightly different reasons. I like the simplicity and elegance of Scheme which barely edges out Common Lisp. And the debugger is really great. It's also weird when he mentioned Forth and Factor. I just downloaded the Factor implementation recently. Weird. Forth is something that I like the elegance and enjoyed Brodie's book immensely. But, haven't played around enough with stack-based languages yet to know whether I like them or not. So much cool stuff!

Anyway, it's a great read. One of these days, I need to do one of these for why I choose Smalltalk. I think the above article was frank about Lisp and we need to be the same about Smalltalk.

I noticed he had a few books that he was planning on reading and are still on my reading list. I wonder if a virtual book club might be in order?

Monday, January 01, 2007

More Having Headaches Over Null

It seems I'm not the only who has heartburn over null in Java. I complained about this problem before and it seems a lot of people are finding the same headaches. The best medicine is to minimize your usage of it and be smart with your patterns (like Null Object, Deaf Object, and Value Object).

Amazon