Dvorak Keyboard Layout

I’ve been using the Dvorak keyboard layout for about a year now. But I’m thinking of switching back. Here are my reasons:
1. Human Compatibility
There are times it is inconvenient to have a different keyboard layout than other people. The most obvious is going over to another person’s computer to help him, be it a coworker, family member or someone else. What I didn’t consider happening is when others use my computer. I didn’t think there would be a use case, but it turns out there is. Coworkers come over to help or do something cooperatively. Or I might be logged into the computer in the conference room and they want to take over the keyboard for a moment. Sometimes, rarely I admit, I let my kids use my computer. All of these times it is a hassle having to switch keyboard layouts.
2. Passwords
I don’t know about you, but I often mistype passwords. And sometimes I have to look at the keys to convince myself I am hitting the correct keys. Well, that doesn’t work when the keys aren’t labelled correctly. And when I’m creating a new password, I want to make sure I am typing what I’m thinking because there will be times I need to type the same password using a QWERTY keyboard, such as at when a computer is booted. Rarely is the keyboard the Dvorak keyboard at bootup or login.
3. Application Compatibility
For whatever reason, Outlook does not like to use the Dvorak layout and I find myself having to use the keyboard setup icon in my tray to change it to use it. Another case that trips up the mapping is when I remote into my work computer (Windows) from my Mac. The layout turns out to be neither. I think some kind of double-mapping is taking place, where QWERTY is converted to Dvorak twice. This makes me have to change my Mac layout to QWERTY for the time I am logged in.
(Edit: Two more applications: games such as Terraria that use WASD for movement and vi which uses HJKL don’t map well in my head.)
4. Shortcuts
I am pretty used to having to reach when I cut and paste, but it is a reach and not nearly as easy and handy with QWERTY.
5. Speed
I’ve been using the Dvorak keyboard for a year now and I wouldn’t say my typing is any faster. The other reason I wanted to switch to Dvorak was to lessen the strain on my hands and possibly lower my chances of carpal tunnel. If that day happens, I’ll deal with it then.

Now, how long is it going to take me to switch back to QWERTY?

Thousands Separator

Thinking outside the box, there are more ways to indicate the thousands separator…

1000000
1000000
1000000
1000000

Not that it is currently possible to style it as such in an input element.

Unless you use ‘o’s for the zeros. That could be done:

10oo0oo

Those take up less space than adding a comma:

1,000,000

In monospace:

1,000,000
1000000
1000000
1000000
1000000

Why new developers should work on legacy applications and seasoned developers on new projects

or

Why my job sucks

My job sucks.

I’ve been moved to a different team again.

Evidently, I’m the shit-polishing guy.

Yes, the guy who loves taking large piles of crap and maintaining them.

Well, the co-workers, pay, benefits, etc., those are all fine. But it’s the work. It hasn’t always been that way, but lately I’ve been busy doing “technical evolution” (my boss’s words, not mine). What does this entail you ask? This is the work necessary to move very old applications off of unsupported hardware onto the currently supported and approved frameworks — read: not the latest and greatest; the stuff that has been approved for 5 years or so. And let me tell you, it isn’t fun. The technology is old. So old that I have to re-learn the stuff. (Throwback every-day-of-the-week anybody?) But that’s not the worst part. It’s the crappy code: poorly written monstrosities that I have to read.

I don’t think clean code was a thing back then.

What I see, and hopefully it is only at my job, let there be a god, is new programmers writing all of the code! New development must be the only way to lure new programmers. (I can’t think of any other reason at the moment.)

I see two reasons poor code is produced by inexperienced programmers.  The first is they don’t realize the importance of maintainable code, or, the second reason, they think they are writing maintainable code.

Let’s discuss the second reason first.

New developers write code that is easy to understand for them. They are under the misconception that the code they are writing is very easy to understand. This is usually because they are the only one looking at their code and it was very recently written. They don’t have the experience of what to do and not do. They don’t know what it means to develop code for maintainability.

Seasoned developers have seen many different projects and learned what works and what doesn’t work. They are more realistic about designing a system. They have witnessed the pitfalls and are less likely to make them.

To address the importance of maintaining code, I suggest “allowing” new developers to support legacy apps. They gain the experience and appreciation of what “bad” (and good!) code can look like and not make the same mistakes. (And at the same time they might gain some business knowledge!)

The other reason I contest my job sucks is because all the new developers get to write code using cutting edge technologies and frameworks and tools. I, on the other hand, don’t get the opportunity to work with this stuff except at home. (Whereas a new developer might not have the same time commitments outside of work and have the time to learn new stuff.) What’s this mean? I am falling behind the times and becoming less relevant.

In conclusion, let the new developers gain the appreciation for and the knowledge how to create maintainable code by maintaining apps and let the experienced developers write new code that the noobies won’t mind maintaining.

Using getters in equals() method

I have an uncontrollable urge to refactor. To a fault. Most everything. If I was cleaning a campsite, I would be putting in indoor plumbing. So, when I opened an old class I changed the old hashcode and equals methods with our team’s standard use of HashBuilder and EqualsBuilder. (The reason for opening the class was to add a toString method.)

@Override
public boolean equals(Object obj) {
    if (this == obj) {
        return true;
    }
    if (obj == null) {
        return false;
    }
    if (!(obj instanceof ${enclosing_type})) {
        return false;
    }
    ${enclosing_type} other = (${enclosing_type}) obj;
    ${builderType:newType(org.apache.commons.lang3.builder.EqualsBuilder)} ${builder:newName(builderType)} = new ${builderType}();
    ${builder}.append(this.${field}, other.${field}());${cursor}

    return ${builder}.isEquals();
}

When I ran the application again (I was trying to find a bug) I wasn’t getting to the same place in the code as before. Stepping through with the debugger I noticed that I was no longer returning “true” during a comparison of the object I had just changed. So I went back to the old version of the equals method. I could not visually see a difference. So I wrote a JUnit test case to test the equals method, specifically for symmetry. That didn’t get me very far; everything passed as expected.

So I ran the program through the debugger stopping in the equals method for comparison. It looked like the passed in object had nulls for everything. I changed my JUnit tests to test for the same setup, but it worked as expected.

So I went back and created 2 equals methods. Then I had each run and if there was a difference between the old equals method and the new equals method, I would just exit the program:

@Override
public boolean equals(final Object obj) {
    // TEMPORARY!!! 
    final boolean newEquals = newEquals(obj);
    final boolean oldEquals = oldEquals(obj);
    if (newEquals != oldEquals) {
        newEquals(obj); // for debugging, I can step through the method again 
        oldEquals(obj); // for debugging, I can step through the method again
        LOGGER.error("newEquals (" + newEquals + ") doesn't equal oldEquals (" + oldEquals + ")!!!");
        LOGGER.error("this = " + this);
        LOGGER.error("obj = " + obj);
        System.exit(1); // TEMPORARY!!!
    } 
    return oldEquals;
}

I re-ran the JUnit test, but still no luck.

I re-ran the application and viola the equals methods were different and the app exited. But what was going on?

I added a breakpoint in the equals method and looked at the state of the variables again. That’s when I noticed the my object being passed in wasn’t what I expected, but some kind of proxy object. I expanded the object and found a target variable. I expanded that and saw the values matched the “this” object!

Equals Comparison Screenshot

I looked back at the equals methods. The original equals method has get() and mine had just the direct access to the member variable. I step throw the call to the get method and found the proxy will load the member variables to their real values.

So, the lesson I learned was that I need to be calling the get methods in my equals method for the object being passed in. I changed my equals template to add a long-winded explanation for the change. Here’s my Eclipse template:

@Override
public boolean equals(Object obj) {
    if (this == obj) {
        return true;
    }
    if (obj == null) {
        return false;
    }
    if (!(obj instanceof ${enclosing_type})) {
        return false;
    }
    ${enclosing_type} other = (${enclosing_type}) obj;
    ${builderType:newType(org.apache.commons.lang3.builder.EqualsBuilder)} ${builder:newName(builderType)} = new ${builderType}();
    // You want to use get() methods because ${enclosing_type} might by a "proxy" that libraries (such as Hibernate with CGLIB) will create. (Hibernate uses proxies for lazy loading.) And if the object is not loaded, then access to the fields directly will yield nulls. But calls to the get() methods are intercepted and the proxy returns the correct value. See https://forum.hibernate.org/viewtopic.php?t=946468
    ${builder}.append(this.${name}, other.get${name}());${cursor}

    return ${builder}.isEquals();
}

Thanks go to this post for helping me understand the issue.

Sublist not Serializable

I guess this was already known by some, but I didn’t know that if you sublist a List that was Serializable, you will get back a list that is not.


import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class SerializableSubListTest {
   public static void main(String[] args) {
     List list = new ArrayList();
     list.add(new Serializable(){private static final long serialVersionUID = 1L;});

     System.out.println("list instanceof Serializable = " + (list instanceof Serializable));

     List subList = list.subList(0, 1);

System.out.println("subList instanceof Serializable = " + (subList instanceof Serializable));
   }
}

list instanceof Serializable = true
subList instanceof Serializable = false

What I Learned At Barcamp

Slash
Biltboard.com will be launching a new app to capture your work in progress process.

Momomaha.com
You have to develop a thick skin to blog about your personal life. And not everyone will like you — accept it.

5 things you can do to motivate your team:

  1. Stand up
  2. Hurry up
  3. Shut up
  4. Pair up – not just programming
  5. Think up – think positively

How To Work with Your Spouse
Communicate! But don’t talk about work at home or home at work.
Having a 3rd person to settle debates is good.

Manage Users like a Roman Centenarian
Accept what is not in your control. Prepare for the worst.

They could charge double the price and it would still be a great deal!

Serialization, Beans and PMD

There is a PMD rule that checks for mutators (getters and setters) on Java Beans: BeanMembersShouldSerialize. I have a lot of these violations in my code. I’d rather understand the issue than just turn it off, but I’m struggling with what it means.

What I learned is: being Serializable does not make a class a Java Bean. And, to be Serializeable, you don’t need mutators.

But PMD thinks my object is a bean. Why? Continue reading

List App

I have an idea for an online list making app. The list can be sorted on any number of attributes (or “sorts”). Attributes can be added at any time and once “activated” you can drag and drop your list to the order you want for that attribute. Then, if you go to another attribute, it again can be drag and dropped into order, but the order is remembered. So if you go back to the first attribute, the items are resorted based on that attribute.

Continue reading