If you're thinking of changing your sprint length, but aren't sure if you should run shorter or longer sprints, here are some heuristics that I've observed. First, I'll give you some background on what I've tried.
At a previous startup, we had 1 week sprints. That worked fine at a startup because everyone did everything. Devs were devs, but they were also client services, designers, DBAs, and devOps. Later, while working at a more established company, we ran three week sprints because there wasn't a pressing reason to change. Let me rephrase that last comment. The established company was used to running sprints like every other established company and 'best practice' was equivalent to whatever was in standard training materials. Now, after switching from a Kanban style (for reasons I won't discuss here,) I am back to 1 week sprints. I feel like that's currently the best match for the company I'm at.
I understand that there are trade-offs in the sprint length that is chosen. So I'll get on with the actual heuristics I'm using to set my sprint lengths.
<------------------------------------------------>
SHORTER LONGER
smaller feedback loop You know your strategy
Forces you to break up issues Priority of features doesn't change often
You may be reactive You're just starting out and going with historical opinion
I hope you can use this scale to better match up your circumstances to an appropriate sprint length for your company.
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.
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.
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.
- Always start by coding
- When you get stuck, follow an online tutorial
- For all the details, read a spec or the official book
- 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.
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.
Subscribe to:
Posts (Atom)



