Pages

Growing from 360 Reviews 18 September, 2015

  Improving in your career is often difficult. Most of the time, people won't tell you what you could be doing better. What's worse, as long as you're doing okay in some area, you have no idea that you're just okay. Being mediocre doesn't elicit response or comment. There's also been a growing trend to focus solely on strengths and not on weaknesses. I understand their arguments, but it's still damaging when a person doesn't know they are weak in an important area. Obviously, based on the title of this post, I'm describing problems that 360 reviews aim to solve.

  I've been toying around with 360 reviews, and like them. From a tools perspective, there are probably many out there that do a great job. Unfortunately, it can take a great deal of time to investigate several solutions, especially if you need to contact the companies, or pay upfront without seeing the systems in action. I wasn't able to find one that I could easily try without signing up, so I created one.

  Take a look at CircleStats. It facilitates the 360 review process and presents the results in a very visual way.


  If not for your team, you should at least know if there's a discrepancy between how you think you're doing in an area, and how others think you're doing in that same area. If taken with a grain of salt, you can learn more about how you're doing from 360 review feedback than you can in talking to peers, direct reports, and managers, even if you talk often.

Pattern Recipes 10 March, 2015

Patterns are mechanisms that invoke an instant understanding of what's happening. At least they're supposed to be. In many scenarios, devs pause blankly for a moment trying to remember what processes that pattern name is supposed to represent.

I wonder if how we index software development patterns is one reason that many people don't remember and use them more often. For example, the Visitor pattern obviously implies that something goes and visits something else. Presumably this happens for decoupling reasons, but other than these basic assumptions, I can't really derive from the pattern name what the pattern really does, or what an optimal use case for it is.

I'm going to propose better names for several well known patterns. The names are longer, but I believe they do a much better job of explaining the pattern. I'll also give a tweet sized explanation. I call these pattern recipes.

Encapsulate a Task == Command
Make an object that can run a task, maybe even undo the task it ran, etc.

Register for Notifications == Observer
Registering and unregistering for notifications by letting an object call a known methods on you.

Algorithm delivery truck == Visitor
Visit me and run an algorithm or method on my data.

Composition over Inheritance == Strategy
Add behaviors by adding objects that encapsulate those behaviors.

Choose Implementation at Runtime == Factory
A class that manages creation, teardown, and resources of related implementations(subclasses).

Choose Implementation Groups at Runtime == Abstract Factory
A class that manages creation, teardown, and resources of implementation groups(factories).

Adapt One Call to Another == Adapter
With API mismatches, create a class that can converts data and bridge any mismatches.

Hide Complex Behavior == Facade
Make code easier to read and use by encapsulating more and hiding dependencies.

Template == Template :)
Like a mix of facade pattern and using an interface or subclasses
one easy call exists, which runs some more complex code.  when that one simple call is running, there is the possiblity for it to ask some subclass or implementing class whether it should execute certain steps.
the simplest version is just a superclass and set of subclasses.
the more complex version then may or may not run specific parts of the complex code.

Mix Composition and Inheritance == Bridge pattern
By using both inheritance and composition, you can decouple more
if you have a long chain of subclasses, try keeping some as subclasses and turn others into a strategy of those subclasses
it also helps when you are mixing and matching classes instead of a Cartesian number of classes, you have just the number needed to represent different objects/behavior instead of objects X behavior.

Prototype == Prototype pattern
A polymorphic version of the copy constructor
deep copy an object in hopes of avoiding lots of init-calc code to recreate the same object

Add One Piece at a Time == Builder
Use if there are too many combinations for constructors...
return self to keep calling setters

Linked Wrappers == Decorator
Create a class for each attribute, rather than for all combination of attributes

Iterator == Iterator
separate algorithm and structure traversal from data container

A Tree with Branches and Leaves == Composite
Treat individual objects and groups of those objects in a similar fashion, like trees with branch and leaf nodes
interface -> both individual and group
this lets you iterate over a mixed hierarchy of this kind smoothly

Reuse Object Parts == Flyweight
Reuse the immutable parts of objects to save memory

I Know My Options == State
An object can change its behavior by changing its internal state. At a simple level, an object knows its state and the options for getting to a new state. Specifically, its state points to different subclasses of some interface dynamically during runtime.

Proxy == Proxy :)
Exactly what it says it is... it sits in front of some class, both the class and proxy implement the same method. The proxy can limit, change, or do whatever it wants to the call. It probably implements all the same methods as the class it is acting as proxy for. no changes to the original object are needed

Push the Problem Up the Ladder == Chain of Responsibility
Several classes that can handle a specific but different case to a problem all implement an interface. Each of these handlers knows about a sibling handler it can pass the problem to if it can't handle the problem.

Language Interpreter == Interpreter
Uses the composite pattern along with a context(parsing) class to process language.

Middleware == Mediator
When objects want to interact, a mediator can encapsulate this activity if there are too many relationships between objects.

Remember States at Points in Time == Momento
Snapshots, some managing class(could store a list of states) that interacts with some state class.

I hope this helps you remember what patterns really mean.

How People Learn Software Languages 28 March, 2014


The idea of a polyglot developer is quickly moving from a state of imagination to a state of reality. I 'm realizing that although there is immense job security for those who know what they are doing in a single language, there are several real benefits to being competent in several languages. 

Some benefits include cross pollinating patterns and faster tool creation. However, I believe the biggest benefit is removing the thought constraints a person can have when they limit themselves to only using one language most of the time.

For many languages, it's not the syntax-sugar a language can have, but their ability to answer questions like "What if I didn't have to...?" or "If I wasn't focused on this area of the problem, would I see a different solution?" 

So, how do you go about being competent in several languages? I recently surveyed a number of software developers, asking them what they prefer to do when learning a new language. This is what I heard.
  1. Always start by coding
  2. When you get stuck, follow an online tutorial
  3. For all the details, read a spec or the official book
  4. To keep it fresh in your memory, submit/merge pull requests in that language

Here are some techniques that were listed by survey responders.
  • Only use what you’re learning (immersion)
  • Start a new project
  • Understand the wrong way to use it
  • Learn it at your own pace
  • Be able to apply each thing you learn
  • Like it
  • Practice it
I wish you the best of luck on your road to polyglot serenity.

SOLID - What It Means For Your Code 14 January, 2014

The SOLID acronym is fairly well known, but the phrase it represents seems to be the only well known part of it. It's a set of letters representing techniques for creating maintainable code. What I've done here is give a brief explanation of each solid principle, followed by a short explanation of how you can apply that principle to your code.

Single Responsibility Principle - Each object should have one responsibility, the granularity of which depends on future changes. Develop with the current feature set in mind and using small objects. The first time that code changes, you'll have a better idea about what the single responsibility should be.

Open/Closed Principle - The goal is to keep the number of code changes low. Requirements will change, but the less code you change, the easier regression testing will be. If a code change requires enough testing that it bothers you, you probably need to adapt the code to be more open for extension and closed for modification. You probably can't always follow this principle, but you can segregate the "open for modification" part while trying to keep it small.

Liskov Substitution Principle - Subclasses and superclasses should be able to run interchangeably without breaking the system. Precondition and postcondition consistency across these objects is a key to avoiding bugs in substitutable types.

Interface-Segregation Principle - Code shouldn't depend on something it doesn't use. If you find you are changing or implementing unused methods, break up whatever you are inheriting or abstracting from.

Dependency Inversion Principle - When you depend on an abstract class, a change in one class has a lower chance of forcing a change in dependent class. You don't need to create an abstraction for every kind of object up front because most abstractions never get a second implementation. Often it is better to wait until the need for a second implementation arises, and then create an abstraction.

Kotter's Steps to Change: A Case Study 08 November, 2013

Recently I've witnessed a change in management. With these management changes, came ideas on how work could be done differently to produce some fantastic results. After everything was said and done, there was an interesting division in the group. Many people liked the old way, and many people liked the new way. Regardless of whether the change was a good thing, I thought it would be interesting to use this experience as a case study for change.

John Kotter has taught leadership courses at Harvard, and is known for an eight step process for bringing about change. These eight steps need to happen in the outlined outlined order. Here are the steps.

Kotter's 8 steps What I observed
1Create urgencyCuriosity/excitement/fear of management changes/new vision
2Form a group of advocatesNew hires under new management
3Get the vision rightWe can be the best...
4Communicate to get buy inHappened hour by hour
5Empower actionBudgets/Autonomy were given
6Create short term wins???
7Don’t give up???
8Work changes into the cultureThis happened early in the process

So, did it work? Many people are now onboard with some general dreams of improvement, but the division I mentioned still exists between those who were for the change, and those who were against it. In this example, three things diverged from Kotter's process:

  1. It is debatable if there were short term wins
  2. The short term wins that existed were not observed by everyone
  3. Overall culture changes happened to early (before the benefits were seen)

It would seem that for this case, John Kotter was correct. I believe that if the three points that diverged from Kotter's process were done as he outlined, the change would have been embraced by most people, and there would be no division.

Here are the takeaways:

  • Short term wins are necessary
  • They need to be seen by everyone
  • Culture can't change until they come
Make sure these steps don't go awry, and you'll see your changes take place with the lowest amount of pushback.

Mobile apps: Native or Web? 18 October, 2013

We usually write web apps in order to sell a product. Often the web app is the product or service we sell. At some point, the question will probably arise: Should we write native mobile versions of our web app. Here are some obvious pros and cons for native mobile apps:
Pros for native apps
1 - Launching an app is usually easier than navigating a browser
2 - You don't have to login every time
3 - You don't wait for script or content downloads, just network calls

Cons for native apps
1 - Apps are harder to update than websites
2 - Development other than web is required (more $ and people)


Under certain circumstances, these pros and cons might not matter. You may be able to save a bookmark on the home screen. Your browser could remember login info for you. Your scripts could be small. You could have continuous deployment. Depending on your site complexity, performance may be the same. Point #1: Not all your users will know-how/want-to/be-able-to bookmark, login, or buy fast devices. Native mobile apps make sense when you are targeting these time-sensitive/budget-conscious customers. That's the customer-resource based reason.

Now, let's look at the rising-competition based reason. Because of the increasing sophistication of browsers and js libraries, a lot of web apps look really good. What then, differentiates your product from a competitor's product? Besides price and the actual idea or feature set, there is UI and UX.

Design is a differentiator. If you believe that good design matters and want a good design, you will have to ask yourself how custom or dynamic your design should be. It's how real and usable things can look. Pixel level UI control is how that's accomplished. Companies have tried to fix this in the web. There's been ActiveX, VML, Browser DirectX, DOM Manipulation, Flash, and Canvas. These were aimed at getting more UI/UX control, some with good frame rates.



So, let's compare UI/UX control on native apps to that of the web using the most direct control mechanisms that users have access to: Canvas Web Elements vs. Custom Android UI Components. Both have pixel level control, but only one is available to every device running that platform. Canvas doesn't work with some browsers, but Custom Android UI Components work with every Android smartphone. Point #2: If you need the extra differentiation in your UI/UX, get more pixel level control. Native mobile apps make sense when you need to differentiate your UI/UX more.

Eventually, mobile OSes will get ironed out and browsers will improve. Everyone will be on fast mobile devices, and have fast connections. Until then however, many native apps just feel awesome when compared to their web counterparts. The only question right now is whether that awesomeness will draw sufficient users to interact with xyz more than a standalone web experience. Hook up some analytics, and you'll get an idea of how you should proceed.

First Impressions: Dart (DartLang) 02 May, 2013


Dart is a language that can compile down to javascript. It also will make command line apps that run in a VM. It has some nice language features, including with being able to write javascript with compile time static type checks. It also includes DOM manipulation based on selectors. I might use this language for some tools.

Tools

Dart tools are pretty good. The Eclipse plugin had an issue, but the standalone Dart IDE worked great. I had no issues with the stand alone version's logging, warnings, errors, running, or auto-completion.


Speed

It's not fast.


Database Access

Fourth party support is needed for database drivers. By this I mean that DB vendors don't have Dart drivers and there is a small amount of support for third party support for the third party vendor drivers.

Intermingling Static and Dynamic Types

int a;
var b;

Implicit String Evaluation

int a = 5;
String b = "I have $a apples";

Underscores Control Visibility

//private:
int _i;
//public:
int i;

Everything is an Object

5.toString();
1 however is not == true

One Line Functions

//Instead of:
int add(int a, int b) {
  return a+b;
}
//You can do this:
int add(int a, int b) => a+b;

Function Parameters Can be Default / Optional

int add(int a, int b, [int c]) {
  if (?c) print(c); //c was passed
}add(a:6, b:2);

Closures

void main() {
  var f = add;
  f(2,3);
}
int add(int a, int b) {
  print(a+b);
}

Typecasting

Typecasting in Dart is a little different. You use the as keyword:
(someObject as Animal).eat();

Shorthand for Caller reuse

Meet the Cascade Operator.
class test {
  func1() {print("in 1");}
  func2() {print("in 2");}
  func3() {print("in 3");}
}
void main() {
  var t = new test();
  t..func1()
    ..func2()
    ..func3();
}

Easy Object Construction

Observe the absence of a constructor body, yet x gets set.
class test {
  int x;
  test(this.x);
}
void main() {
  var t = new test(6);
  print(t.x);
}

Constructor Delegation

Non-verbose constructor delegation.
SomeClass.myDefaultConstructor(x, y) : this(x, y, 0);

The Factory Keyword

There is a factory keyword to designate constructors that will not create new objects, even though you are using the new keyword when executing the constructor
factory Person(String name) {
  //Get a person from cache and return it
}

Implicit getters/setters

By default, getters and setters exist for all class variables. Extra ones can be created like this:
class Person {
  int baggageWeight;
  int personWeight;
  int get totalWeight => baggageWeight + personWeight;
}
void main() {
  Person p = new Person();
  int total = p.totalWeight;
}

Operator Overloading

A great return from C++.
class Person {
  int age;
  int operator +(Person p) {
    return this.age + p.age;
  }
}
void main() {
  Person p1 = new Person();
  Person p2 = new Person();
  p1.age = 20;
  p2.age = 30;
  int total = p1+p2;
  print(total);
}

Annotations

Dart annotations are easy to declare. They're just classes that usually start with lower case characters.
class asdf {}
@asdf
class Person{}

Name Spacing

You can use the as keyword to alias some package you've imported
import package:a/lib;
import package:b/lib as img;

The library and packaging system

So this is a little different than Java/C++ packages/headers
Libraries: The code part of a package that uses library and part keywords to modularize code for a package.
Packages: A package is a config + Library. The config lets you to define dependencies of a package using a Pubspec file (yaml).

Threads (Futures & Isolates)

Futures allow you to run callback after a Timer or thread(Isolate) has completed or erred out.
Isolates(Threads that are isolated from each other) are just functions passed to spawnFunction(). They can talk to other threads using send(), receive(), and call().
import 'dart:isolate';
import 'dart:async';
go1() {
  port.receive((msg, reply) {
    print ('i got $msg');
  });
}
Future go2(){
   Completer completer = new Completer();
   new Timer(new Duration(seconds:1), () {completer.complete("Time is up");});
   return completer.future;
}
void main() {
  var sendPort = spawnFunction(go1);
  sendPort.send("hello"); //Might not get processed if main exits too fast
  sendPort.call("a better way to send").then((reply) {print("sent");});
  go2().then((String result) {print(result);});
}