Wednesday, June 17, 2020
Interviewing Developers
Tuesday, June 16, 2020
Interface or Abstract Class?
- Any time I need a contract between major modules, or between my code and code someone else owns. The contract includes the interface definition(s) and all the types that pass through that interface. That’s a package, and is declared as such.
- Any time I design a general-purpose process which takes different implementations. Right now, for example, I am working on a machine that executes tasks in a sequence depending on the outcome of the previous task. The interface for each task has a single execute method which takes a process status object and returns one of 4 results, all of which are defined in an enumeration.
Friday, April 19, 2013
Sometimes You've Just Gotta Draw a Line
<div
style="height: 14px;
color:white; background:white;
position:absolute; left:77px; top:8px;
transform:rotate(27deg);
-ms-transform:rotate(27deg); /* IE 9 */
-webkit-transform:rotate(27deg); /* Safari and Chrome */
width:1px"/>
And here's a general-purpose kit for drawing lines a lot, which provided the clues I needed:
http://monkeyandcrow.com/blog/drawing_lines_with_css3/
So now you know.
Saturday, February 2, 2013
An Unreasonable Man
It wasn't until about 3 hours later that I realized what at least part of the answer is, and it's the root of what's been "wrong" with this team, and indeed, what's "wrong" with many development teams. I am emphatically not a reasonable man. Where making software is concerned, I'm a distinctly unreasonable man. In fact, I'm pretty sure I'm a complete son-of-a-bitch. And the people I have loved working with the most are, themselves, unreasonable people. As you might imagine, this can cause a lot of friction in a development team, if the rest of the team is full of reasonable people who expect reasonable behavior.
In my defense, I'm pretty sure you can't make adequate software by being reasonable.
Monday, July 23, 2012
A Scout is Trustworthy
They say once and Eagle, always an Eagle. I always believed that. The latest overt action by the BSA has caused me to rescind that belief. I'm sending my badge back, and I'm explaining my reasoning here.
Wednesday, May 16, 2012
OO, Ward, and Creole
Some solid reading on what OO means, and how to test it:
http://www.drdobbs.com/testing/240000411
Ward Cunningham on wiki, languages, and doing the smallest possible thing that works:
http://www.drdobbs.com/jvm/240000393
and finally: how to make your wiki talk to others' wikis:
http://www.wikicreole.org/
Tuesday, February 21, 2012
Software Fragility
Wednesday, October 5, 2011
RIP, Steve
Sunday, September 25, 2011
Moving away from Google
In the early days, PCs (well, except for Macs) were hard to use, had horrible interfaces, minimal software choices (WordStar, VisiCalc, dBase II, and AutoCAD were the exceptions), and were in huge demand everywhere. Why? I think it was largely because they allowed us to control our work. We had word processing, databases, and CAD systems before PCs. They were controlled by others--we could be locked out, inconvenienced, our work confiscated and our access revoked by those in control, without appeal and without warning.
Sound familiar?
Wednesday, June 29, 2011
Six steps to JBoss (and Tomcat) with IIS 7
Wednesday, June 1, 2011
Java Components and Package Visibility
Tuesday, January 18, 2011
Creating Healthy Craftsmen
Wednesday, January 12, 2011
Documentation in the wild
In this particular project, this is generally a Good Thing--the code in question is clear, well written, and (ahem) completely without comments. I'm not having a lot of trouble understanding it, overall, because it really is very good code. But... I've spent 2 days trying to figure out how one important feature works.
http://thedailywtf.com/Articles/Documentation-Done-Right.aspx
'Nuff said.
Wednesday, October 27, 2010
Kanban in IT
Saturday, March 20, 2010
Sucking Less: Checking In More Often
I'm fairly fearless when coding, which means that about once a week, I delete a huge chunk of something I should've kept, or change something into something unrecognizable, thereby inadvertently breaking a dozen unit tests. When I discover the problem, usually about 4 hours later, I no longer have any idea what I did that made the bad thing happen. Then I spend another 2 or 3 hours figuring out what I broke and fixing it. Ugly.
On my personal projects, I check in code every time I get a unit test working. My checkins are something like 15-20 minutes apart. On projects I get paid for, though, checking in means running the whole unit test suite, and that can take 10 minutes (on a good project) or 2 hours (on a bad one)--so I don't do it very often. That's when I get into trouble. I've been meaning to solve that problem for some time, and Joel Spolsky's blog topic last Wednesday (Joel on Software) finally kicked me in the pants. It took 15 minutes to solve the problem; here's how I did it.
Wednesday, March 3, 2010
Annotating Custom Types in Hibernate
Sunday, February 21, 2010
java.util.DuctTape
The proposed class, java.util.DuctTape, is designed as a general purpose fix for a variety of commonly-observed situations in production code. It serves as a temporary patch until a permanent solution is developed and deployed.
Wednesday, February 17, 2010
Database/Code impedance mismatch
I love natural keys in database design. You have to pay attention, though: the natural impedance mismatch between a programming language representation and the database representation of the key can bite you.
Consider an object whose primary key might contain a date--say, a change log record. Oracle and DB2 both store a DATE as a time containing year, month, day, hours, minutes, and seconds. No timezone. The natural mapping for a Java tool like Hibernate is to map to a java.util.Date, which stores the Date as a time in milliseconds since the epoch GMT, and then maps it to whatever timezone is set on the machine where the code is running for display and conversion.
Now consider what might happen (especially if our change log record is attached to some parent object);
- We create and save the object; it is persisted. The local cached copy contains a non-zero value for milliseconds, but the database has truncated the milliseconds value and saved it.
- Later on in the code somewhere, we have reason to save the object again, perhaps as part of some collection operation.
- Hibernate looks in its cache, compares it with the database, and notes that the values of the Date don't match--so it tries to save the value again.
- The database dutifully tosses out the spare milliseconds, and bam! we have an attempt to re-insert an existing record, so it throws an exception.
The easy fix in this case is to declare a class which matches the database representation--in this case, a good choice would be to declare a new class which truncates the milliseconds. A modest example is shown below:
/**
* Public Domain; use or extend at will.
*/
import java.util.Date;
public class DbDate extends Date {
/** increment if you change the state model */
private static final long serialVersionUID = 1L;
/** @see java.util.Date#Date() */
public DbDate() {
long t = getTime();
setTime(t - t%1000);
}
/** @see java.util.Date#Date(long) */
public DbDate(long t) {
super(t - t%1000);
}
/** @see java.util.Date#setTime(long) */
@Override
public void setTime(long time) {
super.setTime(time - time%1000);
}
}
Also note that if you declared the database column as a TIMESTAMP, the Java and database representations more-or-less match--avoiding, in this case, this kind of problem. Note that Oracle doesn't support TIMESTAMP_WITH_TIMEZONE in a primary key, and DB2 doesn't implement TIMESTAMP_WITH_TIMEZONE at all--as of the last time I had access to DB2.
Dealing with timezones is another topic entirely--one which I'll take up in a future post.
