Wednesday, January 11, 2017

Software Engineer's Personal Development Ideas


  1. Take additional programming courses (even just audit them) at some of the schools around Dallas. Some of the community colleges have good classes. 
  2. Read, read, read. 
    1. Anything by Robert Martin 
      1. Agile Software Development, Principles, Patterns, and Practices (known as the PPP book) 
      2. Clean Code: A Handbook of Agile Software Craftsmanship 
      3. The Clean Coder: A Code of Conduct for Professional Programmers 
      4. Follow him on Twitter: https://twitter.com/unclebobmartin 
    2. Check out books on: 
      1. The Pragmatic Bookshelf (www.pragprog.com) – by the guys who wrote Pragmatic Programmer (another good read) 
      2. Manning (www.manning.com) 
    3. Check out the Head First series of books at oreilly.com. And other books there as well, but the Head First books are good intro books to a lot of ideas.
      A couple of good starters from them are: 
      1. Head First Object-Oriented Analysis and Design 
      2. Head First Design Patterns 
  3. Check out the local user group community. Most communities have very active .Net and Java User’s groups. 
  4. Find out who the movers and shakers are in the industry and follow them on Twitter and read their blogs. 
  5. Learn about the industry or line of business you are working in. Most organizations have books available, like ABA (www.aba.com) for the banking industry. Have you ever read ABA's "Principles of Banking"? 
  6. Find an Open Source project that you are interested in and get involved. 
  7. Create your own Open Source project. 
  8. Learn git. 
  9. Learn about dependency injection (or dependency inversion) and try it out. 
  10. Learn what SOLID means 
  11. Learn what GRASP means 
  12. Learn what coupling and cohesion are and what is good and bad about them. 
  13. Write a simple piece of software using TDD. Learn what TDD is. Try to incorporate it into your normal development process. 
  14. Do Lunch and Learn presentations – nothing helps you learn something like having to teach it to others. We do this every Friday (except when we don’t :-)). Each team member takes turns presenting something new to the team and then we discuss it. This also helps develop good presentation skills. We critique the presentations as well to help junior members (and even the senior members) of the team learn. 
  15. Go to at least one good technical conference a year. Several of us started attending the Strangeloop conference in St. Louis about 3 years ago. I wouldn’t miss it. Lots of good ideas, the current buzz in what is going on in software development. I have learned two new languages inspired by sessions at Strangeloop. It is also relatively inexpensive for a conference. 
  16. Learn at least one new language every year. You may learn something you will never actually use in a real system, but exposure to the ideas and thoughts behind different languages help expand your own thinking and problem solving skills. And you never know. I learned Groovy last year and we are using it where appropriate today at my current job. I also learned Erlang which I will probably never use to develop a customer system, but it taught me a lot about thinking in functional programming languages. For the .Net guys, I would definitely look at F#. 
  17. Learn a new database every year; learn a new tool each year; learn a new web design approach each year; you get the idea. 
  18. Learn another operating system beside Windows. Port some code from one to another. Look at Raspberry PI. 
  19. For web development, check out todomvc.com. It shows how to write a simple to do list in a number of different web frameworks, so it gives a basic intro to web programming and lets you compare approaches. 
  20. Check out the Tutorials section on topcoder.com. Pick a hard problem, design a solution, algorithm, and code it. (This is actually one of the things Google will tell you to do before an interview with them.) 
Read Clean Coder for more ideas from Uncle Bob. In that book, he suggests that someone interested in growing in their career as a software engineer will spend about 20 hours a week outside of work on their career. Of course that assumes you aren’t working 60-80 hours already at your day job, but he talks about that, too :-).

Sunday, April 6, 2014

Using the "parameter object" pattern reduces coupling and code changes

I have seen a pattern before something like this:
ThingA thinga = createThingA()
ThingB thingb = createThingB()
ThingC thingc = createThingC()
ThingD thingd = createThingD()
 
HandlerA handlera = new HandlerA()
 
handlera.process(thinga, thingb, thingc, thingd)
 
HandlerA {
 void process(ThingA thinga, ThingB thingb, ThingC thingc, ThingD thingd) {
    handlerb.process(thinga, thingb, thingc, thingd)
 }
 
HandlerB {
 void process(ThingA thinga, ThingB thingb, ThingC thingc, ThingD thingd) {
    thinga.doSomething()
    thingb.doSomethingAlso()
    handlerc.process(thinga, thingb, thingc, thingd)
 }
 
HandlerC {
 void process(ThingA thinga, ThingB thingb, ThingC thingc, ThingD thingd) {
    thinga.doSomethingMore()
    thingc.doSomethingAlso()
    handlerd.process(thinga, thingb, thingc, thingd)
 } 
 
HandlerD {
 void process(ThingA thinga, ThingB thingb, ThingC thingc, ThingD thingd) {
    thingd.doSomethingMore()
 }
Notice that ultimately it is not until 4 layers deep that thingd is actually used, but because the objects are all created and owned at the top level and handlerd is the class that needs thingd, it has to be passed all the way through the various layers, even though only handlerd cares about thingd. This is a bad form of coupling and should smell funny.

However, this gets really bad when requirements change and now we need a thinge which is created and owned at the top level and handlerd needs it to implement the new changes. Now we have to change the method signature of all the higher up methods to pass this value in. Now this stinks, not just smells.

Assuming that we need to pass these values around, a better way is to create another class, maybe HandlerContext. HandlerContext contains all the things. And only the HandlerContext is passed to each handler. Then when need to add a new thing, only the HandlerContext class changes and only handlerd even needs to know about thinge. No signatures change.
ThingA thinga = createThingA()
ThingB thingb = createThingB()
ThingC thingc = createThingC()
ThingD thingd = createThingD()
ThingE thinge = createThingE()
 
HandlerA handlera = new HandlerA()
HandlerContext context = new HandlerContext(things, thingb, thingc, thingd, thinge)
 
handlera.process(context)
 
HandlerA {
 void process(HandlerContext context) {
    handlerb.process(context)
 }
 
HandlerB {
 void process(HandlerContext context) {
    context.thinga.doSomething()
    context.thingb.doSomethingAlso()
    handlerc.process(context)
 }
 
HandlerC {
 void process(HandlerContext context) {
    context.thinga.doSomethingMore()
    context.thingc.doSomethingAlso()
    handlerd.process(context)
 }
 
HandlerD {
 void process(HandlerContext context) {
    context.thingd.doSomethingMore()
    context.thinge.doSomethingMore()
 }
A nice reference page for this is located at http://sourcemaking.com/refactoring/introduce-parameter-object. He also does a nice job about showing how to more effectively encapsulate common logic associated with parameter objects as well.

Saturday, March 22, 2014

Why I love Groovy (and why you should try it)

I recently had to create a new simple class. Its purpose was to simply encapsulate a String value, but because it was a business domain value and I needed to be able to find usages later in the code, it made sense to create its own class instead of just using String (that is worth another discussion). It addition to just wrapping the string, there were some other processes that were needed to relating to the value. Mainly that the input from the user could be a list of values and I needed to be able to parse those into the individual values and needed to do that in only one place. So here is the class in Java. I have removed all the blank lines and any comments so I can easily compare it next with the Groovy version.

(Note -- another discussion can be had on the merit of including all the static methods in this class :-))

package test.application;
import java.util.List;
import com.google.common.collect.Lists;
public class ApplicationName {
    private final String value;
    public ApplicationName(String applicationName) {
        this.value = applicationName;
    }
    public static ApplicationName from(String applicationName) {
        return new ApplicationName(applicationName);
    }
    public static List<ApplicationName> listFrom(String applicationName) {
        List<ApplicationName> list = Lists.newArrayList();
        String[] split = applicationName.split(",");
        for (String s : split) {
            list.add(from(s));
        }
        return list;
    }
    public static String toString(List<ApplicationName> list) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < list.size(); i++) {
            if (i > 0) sb.append(",");
            sb.append(list.get(i).value);
        }
        return sb.toString();
    }
    public List<ApplicationName> asList() {
        return listFrom(value);
    }
    public String getValue() {
        return value;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ApplicationName that = (ApplicationName) o;
        if (value != null ? !value.equals(that.value) : that.value != null) return false;
        return true;
    }
    @Override
    public int hashCode() {
        return value != null ? value.hashCode() : 0;
    }
}

And here is the Groovy version. As you can see it is much shorter and (if you know the groovy syntax) easier to read.

package test.application
import groovy.transform.Canonical
@Canonical
class ApplicationName {
    final String value
    public static ApplicationName from(String applicationName) {
        new ApplicationName(applicationName)
    }
    public static List<ApplicationName> listFrom(String applicationName) {
        String[] split = applicationName.split(",")
        split.collect() { name -> from(name) }
    }
    public static String toString(List<ApplicationName> list) {
        list.collect { n -> n.value }.join(',')
    }
    public List<ApplicationName> asList() {
        listFrom(value)
    }
}

Here are the statistical differences in the two. As you can see, the Groovy code is less than half the Java code size. This is a significant impact on how quickly code can be written as well as reducing "technical debt". Some of the differences are that Groovy will generate the getter for the value. And the @Canonical annotion will generate the constructor, the equals and hashCode methods, and also the toString (which I didn't even include in the Java version, but it would have added even more code to the statistics) – significantly reducing the boiler plate code that needs to be written for Java. Groovy also returns the last value in the method automatically without having to specify "return". And you don't have to use ";" either.


Java Groovy % decrease
Lines 46 19 58.7%
Characters 1574 625 60.3%

In addition, let's look at the Unit test cases written in both Java and Groovy. While not as significant in code reduction, the Groovy code is still easier to write. Also, of note, the Groovy unit test class can be used to test both the Java and Groovy versions of the real class. So even if you have to write the original class in Java, you can still write the unit tests in Groovy and pick up some development time.

package test.application;
import static org.junit.Assert.assertEquals;
import java.util.List;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ApplicationNameTest {
    @Test
    public void testFrom() {
        ApplicationName name1 = ApplicationName.from("test,sam");
        ApplicationName name2 = new ApplicationName("test,sam");
        assertEquals(name1.getValue(),"test,sam");
        assertEquals(name1, name2);
    }
    @Test
    public void testListFrom() {
        List<ApplicationName> list = ApplicationName.listFrom("test,sam");
        assertEquals(list.get(0).getValue(), "test");
        assertEquals(list.get(1).getValue(), "sam");
    }
    @Test
    public void testToString() {
        List<ApplicationName> list = ApplicationName.listFrom("test,sam");
        assertEquals(ApplicationName.toString(list), "test,sam");
    }
    @Test
    public void testAsList() {
        List<ApplicationName> list = ApplicationName.listFrom("test,sam");
        ApplicationName name1 = ApplicationName.from("test,sam");
        assertEquals(name1.asList(),list);
    }
}
package test.application
class ApplicationNameTest extends GroovyTestCase {
    void testFrom() {
        def name1 = ApplicationName.from("test,sam")
        def name2 = new ApplicationName("test,sam")
        assert name1.value == "test,sam"
        assert name1 == name2
    }
    void testListFrom() {
        def name1 = ApplicationName.listFrom("test,sam")
        assert name1.value == ["test","sam"]
    }
    void testToString() {
        def name1 = ApplicationName.listFrom("test,sam")
        assert ApplicationName.toString(name1) == "test,sam"
    }
    void testAsList() {
        def name1 = ApplicationName.from("test,sam")
        assert name1.asList() == [ApplicationName.from("test"), ApplicationName.from("sam")]
    }
}

Statistics for the unit test classes:
Java Groovy % decrease
Lines 32 21 34.4%
Characters 1200 760 36.7%


So overall for writing both the original classes and the unit test cases, we have:

Java Groovy % decrease
Lines 78 40 48.7%
Characters 3774 1385 63.3%