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.
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:
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:
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 | |
| 1 | Create urgency | Curiosity/excitement/fear of management changes/new vision |
| 2 | Form a group of advocates | New hires under new management |
| 3 | Get the vision right | We can be the best... |
| 4 | Communicate to get buy in | Happened hour by hour |
| 5 | Empower action | Budgets/Autonomy were given |
| 6 | Create short term wins | ??? |
| 7 | Don’t give up | ??? |
| 8 | Work changes into the culture | This 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:
- It is debatable if there were short term wins
- The short term wins that existed were not observed by everyone
- 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.
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');
});
}
Futurego2(){
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);});
}
First Impressions: Go (GoLang) 30 April, 2013
Go is a language that mixes old and new concepts. They use automatic memory management, but also bring back pointers and unsigned primitives. Other differences include forcing defensive style. It is a statically typed language, which helps find errors at compile time rather than waiting for a runtime error/test to catch the problem. Something else that I really like is the basic web site readiness. Go comes built with web technologies built in.
I think it's a decent language, but for me to spend more time using GO, it needs:
1 - a unique name (try to google 'go' + something)
2 - to be built out more (ex: compiler optimizations, improved web site readiness)
3 - better data integration (it feels like the only good support is for AppEngine's Datastore)
The use of GO seems to be restricted to a few startups, or to tools of better known or longer lived companies. Here's a list of some features I wanted to highlight:
Tools
The tools are still ramping up. Getting automatic building and completion on OSX seems like it was more of a pain than it should have been. The windows setup was pretty simple. It gives you an idea of what is available, but isn't quite as smooth as your standard Eclipse or VS auto-complete.
Speed
Another thing that needs some love is the compiler optimizations. I ran a couple of benchmarks. I know these are specific cases, but for a compiled binary, it should have out preformed Java. Instead Java was at least twice as fast. The two tests I ran were SHA2 generation, and Fibonacci generation.
Built In Web Framework
There is no need for an additional or external web container. No Tomcat. No Rails. It runs it's own server and it's built in.
package main
import (
"net/http"
)
func main() {
http.HandleFunc("/", someHandlerFunction)
http.ListenAndServe(":8080", nil)
}
HTML Templating
Built into the language is the ability to markup HTML with GO data:
.go file:
x, y := template.ParseFiles("some.html")
x.Execute(httpResponse, dataModel)
.html file:
<a href="someLink">{{.LinkTitle}}</a>
Multiple Return Values
func getPair() (int,int) {
return 1,2
}
Signed & Unsigned Types
a int8 = 127b uint8 = 255
Forced Style
{}s required for one line if/for blocks. Not doing this creates a compile time error. Also, else statements must be on the same line as it's braces.
Right:
if i==0 {
//Something
} else {
//Something else
}
Wrong (no braces):
if i==0
i = -1
Wrong (closing if/starting else braces are on different lines):
if i==0 {
}
else {
}
Unused Code
Unused code (variables/imports/etc.) will create compile time errors instead of warnings.
Initializing Statements for if Blocks
if i:=math.Max(a,b); i==5 {
//Do something, possibly using i
} else {
//Use i here too
}
Easy Small Object Construction & Assignment
Java:
class Pair {
int a;
int b;
public Pair(int a, int b) {
this.a = a;
this.b = b;
}
}
new Pair(1, 2);
V.S.
GO:
type Pair struct { a int b int}Pair{1,2}
Pointers (No Pointer Arithmetic)
func mod(i *int) {
*i++
}
func main() {
i:=4
mod(&i)
fmt.Println(i)
}
Variable Struct Construction Args
type fourPropertyStruct struct {
a,b,c,d int
}
func main() {
fmt.Println(fourPropertyStruct{b:4,d:7})
}
Simpler Syntax for Arrays
someArray[firstElement:lastElement-1] will return the appropriate subset of someArray[]. Missing indexes imply beginning or end ([:3] or [3:] for example)
One Form of For
Instead of a multi step for and a simple iterator based for, one form is used:
var list = []int{1, 2, 4, 8, 16}
func main() {
for i, v := range list {
fmt.Printf("index: %d, value: %d\n", i, v)
}
}
To keep a single For form, _ is used when you don't need either the index or value
for _, value := range pow {
fmt.Printf("%d\n", value)
}
Object Creation
new creates New Objects
make creates New Arrays & Maps
a:=new(SomeStruct)
b:=make([]int, 5)
Maps are declared: map[keyType]valType
maps can return a key, boolean pair describing what the value is/if the key existed
Simultaneous Assignment
x,y = y,x+y
Temp variables are no longer needed!
No Break Statement Needed in Switch Statements
switch ret {
case 1: //Do something
case 2: //Do something else
default:
}
No Classes. Just Structs with Methods Appended
interface types can have method signatures defined in them. a type implements an interface when it has those methods, not by tagging it as that interface
type Greeter interface {
Greet() string
}
Errors Implemented by Having an Error()(string) Method
You don't tag a struct or object with an interface. If an object has the methods defined in an interface, it is automatically-polymorphically-compatible.
Easy Threading
go someMethod, will launch that method on a separate thread. When you combine this with channels (a report back mechanism), concurrency becomes simple compared to many other languages:
func getInfoFromThread(x chan string) {
x <- "hi"
}
func main() {
x := make(chan string)
go getInfoFromThread(x)
z := <-x br=""> fmt.Println(z)
}-x>
Transistors and Computer Science 22 March, 2013
It feels like there are a multitude of developers who talk about Arduino, Raspberry pi, and computer hardware in general. This being said, I haven't observed many that add this type of knowledge to their arsenal. Over the last year, I caught myself doing the same thing, so I finally took the plunge.Understanding topics like Ohm's law and current are necessary to get into any detail. If you're a hobbyist, Maker Shed has a great intro. But for a developer looking for the executive summary, the transistor is a good place to start. Not only is the transistor something your dev box is based on, but it has the fascinating application of being able to represent boolean logic in hardware. This lays the foundation for all those truth tables you did in your Computer Architecture/Systems classes.
Here's an example.
Inputs: A, B
Output: C
Here's a truth table for C = f(A, B):
| A | B | C |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
A boolean expression that calculates A and B based on this truth table would be:
A AND B, also commonly written as A∧B or A && B.
If both A and B are 0, or either A or B are 0, C equals 0.
C is only 1 if both A and B are 1.
Here's where transistors come into play. Basic Bipolar Junction Transistors take two inputs, and have a single output. They are perfect for creating AND, OR, NOT, XOR, NAND, and NOR operations. Transistors may need to be chained together while acting as a series of cascading switches to get such benefits, but they can do it.
Once we chain enough of these logic gates together, we can do more complicated computations.
Simple, yet interesting.
From Strategy to Marketing 24 May, 2011
At a high level, marketing can be broken down into four steps:
Marketing is all about capturing value from targeted customers by creating profitable relationships with them and building value for them. This requires a great deal of strategy.
During the screening and concept phases of product development, a need is targeted. This need is compared to current solutions using both marketing concepts and value propositions.
Effective segmentation means that a segment and resulting reactions must be:
One way to identify holes in the market, or segments that are not being served is to use positioning maps. An example is shown below:

To communicate this to the customer, you create a positioning statement. This statement takes the form of:
"To our is that "
The marketing mix supports the positioning strategy and statement.
- Understand needs
- Plan for meeting those needs
- Communicate & execute the plan
- Build relationships
Marketing is all about capturing value from targeted customers by creating profitable relationships with them and building value for them. This requires a great deal of strategy.
During the screening and concept phases of product development, a need is targeted. This need is compared to current solutions using both marketing concepts and value propositions.
Targeting and Segmentation
Markets can be segmented in many ways. Segment variability and available resources determine a which segments are targeted (chosen as the buyers or consumers). The most common segments are based on:- Geographic
- Demographic
- Age
- Lifestyle
- Gender
- Income
- Psycographic
- Behavioral
- Occasion
- Benefit
Effective segmentation means that a segment and resulting reactions must be:
- Measurable
- Accessible
- Substantial
- Differentiable
- Actionable
One way to identify holes in the market, or segments that are not being served is to use positioning maps. An example is shown below:

Marketing Concepts
Concepts in marketing (your overall strategy for selling) include:- Availability and affordability
- High quality and high performance
- If large scale marketing and selling efforts take place
- Knowing the needs and wants of the consumer
- Long term interests of consumers in business and society
Value Propositions
A value proposition (all the value that you are offering) points you in the direction of your positioning strategy. A positioning strategy is generally one of the following:- More for more
- More for the same
- More for less
- The same for less
- Less for much less
To communicate this to the customer, you create a positioning statement. This statement takes the form of:
The marketing mix supports the positioning strategy and statement.
Subscribe to:
Posts (Atom)








