Why Java Layout Managers are not a Strategy Pattern (any more...)
Post date: Oct 6, 2013 4:19:50 PM
Apparently I'm all bloggy today. Fits and spurts, I suppose.
One thing I see occasionally is that Java's AWT/Swing Layout Manager system is an example of the Strategy design pattern. The more I learn about layout managers (and Strategy), the less I agree.
First off, a review of Strategy. The relevant highlights are:
- Strategy makes a family of algorithms interchangeable.
- Strategy de-couples the Client (user) of an algorithm from the specific implementation of that algorithm.
To me (and I'll welcome someone pointing out where I get this wrong), the heart of the Strategy pattern is the ability to swap-out one implementation for another -- and have the user (client) of the Strategy be none the wiser.
Now, on to layout managers. In Java, there are two interfaces, LayoutManager and its extended interface LayoutManager2, that specify how layout managers should behave. Looking at the methods required by LayoutManager only, I'm actually comfortable calling it Strategy. So any class that implements only LayoutManager (but not LayoutManager2) should be interchangeable with any other that does the same...which basically leaves FlowLayout and GridLayout. It's important to recognize that both of these layout managers are agnostic of the Components being added to them; as a component is added, the layout manager finds a place for it.
LayoutManager2 breaks this component-agnostic system by incorporating the idea of constraints. Its addLayoutComponent() method allows implementing classes to associate a constraints object with a specific component in the GUI. An example is a constraint that says to put a JButton in the NORTH position of a BorderLayout -- the layout manager can't meaningfully position the JButton without this extra object that effectively couples the JButton (part of the layout manager's client, probably a JPanel or similar container) to the client.
As a more visceral example, create a JFrame with a bunch of buttons and labels and such and set its layout manager to FlowLayout. Then try to set it to BorderLayout or GridBagLayout. It might technically work, in a trivial sense, but you're missing out on the power of those layout managers if you don't go further and add in constraints. This violates what I see as the heart of Strategy -- that implementations of the algorithm be interchangeable.
All that said, this is not a critique of layout managers. Layout managers like GridBagLayout and SpringLayout are powerful and useful. I just don't think they can be called a Strategy pattern. My suspicion is that the original idea behind layout managers was that they were intended as a Strategy, but that the hard realities of GUI layout (especially with Java's can't-win goal of platform-independent GUIs) meant the API designers had to break it later on down the line.