Freitag, 2. Oktober 2015

Technical Debt in Scrum - How to Pay Them Back


A lot of Scrum teams face the challenge of balancing the implementation of new product features and keeping the code base clean and maintainable. Very often the product owner pushes the development team to ship an increment with new features at the end of every sprint. The development team might not find the time to keep the code base clean and maintainable. With every refactoring that the developers feel a need for but that is not done, the team increases its technical debt. If the technical debt is not payed off, it will slow down the team's productivity in the long run. In this post I propose a way of balancing the implementation of new product features and the reduction of technical debt.

A Scrum team pulls work off the product backlog (PB). The PB is maintained by the product owner. To enable the development team to work on new product features and the reduction of technical debt
I propose the use of another backlog: the technical debt backlog (TDB). The TBD is maintained by the development team. Every time a developer feels the need for a refactoring and is not able to do it, she adds an item to the TDB. The development team gets together at least once per sprint to groom the TDB. They present the items to each other, estimate and prioritise them. The estimation can be done with the planning poker technique. During sprint planning 1 the team pulls items from the product backlog and the technical debt backlog.

The use of a separate backlog for technical debt has the following advantages:
  • technical debt is visible to the development team and the product owner
  • the reduction of technical debt is seen as part of product development
  • the development team is engaged to increase the value of its code base
What is your approach to reduce technical debt? Or even better: how do you avoid technical debt?

Donnerstag, 19. Februar 2015

How to write a unit test for your iOS app

Here are some general guidelines that I am sticking to when I write a unit test for an iOS app.

Unit tests for your System Under Test (SUT) go into a file called SUT_Tests.m. This file contains a class called SUT_Tests. Replace SUT with the class you are testing; e.g. WebService_Tests.
This class has the following features:
  • Inherits from XCTestCase
  • Has no header file. The class declaration goes into SUT_Tests.m.
  • Declares the SUT's private properties and methods in a category called Testing
  • Has no private methods. Unit tests should share as less code as possible - they need to run in isolation. Having private methods tends to sharing state among unit tests which breaks isolation.
  • Has short methods. Try to stick to a maximum of 15 lines per test* method. If you need more lines, try to break up the method that you are testing or handle cases like testing a method with nil and @"" in separate methods. 
  • Methods have self explanatory names. E.g. testMethodXYWithNil, or testMethodXYWithEmptyString
When writing your tests, keep the FIRST principle in mind.
You can use this as a template:

#import 
#import 
#import "SUT.h"

#pragma mark - private declarations

/*
 * Declare your SUT's private properties and
 * methods in this category.
 */
@interface SUT (Testing)

@property (nonatomic, strong) id aPrivateProperty;

- (BOOL) aPrivateMethod;

@end

#pragma mark -

/*
 * The class declaration goes into the .m file.
 */
@interface SUT_Tests : XCTestCase

@property (nonatomic, strong) SUT *sut;
@property (nonatomic, strong) id   sutMock;

@end

#pragma mark -

@implementation SUT_Tests

- (void)setUp 
{
    [super setUp];
    
    self.sut     = [[SUT alloc] initWithDesignatedInitializer]];
    self.sutMock = OCMPartialMock(self.sut);
}

- (void)tearDown 
{    
    [self.sutMock stopMocking];
    
     self.sutMock = nil;
     self.sut     = nil;
    
    [super tearDown];
}

#pragma mark - tests

/*
 * Your unit tests go here.
 */

- (void)testYourSUT 
{

}

Freitag, 14. Dezember 2012

Recommended Start-Up Books

Hi folks,


if you ever wanted to found a start-up and are still looking for some advice, I recommend the following three books that helped me to sharpen my understanding of a start-up's basic building blocks and it's inner workings.


The first one is Business Model Generation: A Handbook for Visionaries, Game Changers, and Challengers. This book will help you to define your initial product vision in terms of a business model. This books introduces you to a tool called the Business Model Canvas (BMC). The BMC will guide you step-by-step through the creation of a business model. Once you have defined your business model with the help of the BMC, you will find it much easier to communicate your business model to others and have a good starting point for your start-up.

The second recommended reading is The Lean Startup by Eric Ries. Eric introduces you to a methodology - the Lean Startup Methodology -  which describes how you should run your start-up. While the Business Model Canvas is used to define your start-up's business model, the Lean Startup Methodology describes how you should implement this business model: incrementally in short iterations. It will help you in managing your precious time and money before running out of them. If you have never run a start-up before, you will find a perfect coach in Eric.




Ash Maurya combines the Business Model Canvas and the Lean Startup Methodology in his book Running Lean. He presents an adopted version of the Business Model Canvas called the Lean Canvas. He shows you how to apply the Lean Startup Methodology in conjunction with the Lean Canvas. The two previous books teach you the tools. This book shows you how to use these tools. Ash takes you through the development of one of his start-ups step-by-step. He defines a Lean Canvas and walks you through the complete implementation of an initial product vision. If you have read "The Lean Startup" and cannot wait to apply the Lean Startup Methodology, read this book before you get your hands dirty.

Dienstag, 14. August 2012

iOS Multithreading: Thread Safety in iOS Applications

In this post I will exemplify what it means if the objective c code of your iOS application is not thread safe. First, I will cover some basics that will be helpful to understand thread safety. With these basics at hand we will do some experiments to explore the nature of not thread safe code. Finally, I will outline a tool which we use at orderbird to analyze our code for potential thread safety issues.

This post does not cover tools or strategies for multi-threaded programming but will point you to sources that cover this topic.

1) Threading Basics


When your app is started iOS creates a new process and memory is allocated for this app-process. In simplified terms, the memory of an app-process consists of three blocks (A more detailed explanation of the memory layout of C programs can be found here):
The program memory stores the machine instructions your objective c code has been compiled to. Which instruction is executed next is indicated by the Instruction Pointer (IP).

The heap stores objects which are created with [… alloc] init].

The stack is the memory area that is used for method invocations. Methods store things like their parameters and local variables on the stack.

By default an app-process consists of one thread - the main thread. If your iOS app uses multiple threads, all threads share the program memory and the heap but each thread has its own instruction pointer and stack. This means that each thread has its own program flow and if a method is called on one thread, the parameters and local variables cannot be seen be any other thread. But the objects that are created on the heap can be seen, accessed, and manipulated by all threads.

2) Experiment


Now, let us start our little experiment. Open Xcode and create a new project (choose the template "Empty Application"). Create a class named "FooClass" as depicted in the following:

 @interface FooClass {}  
 @property (nonatomic, assign) NSUInteger value;  
 - (void)doIt;  
 @end  
   
 @implementation FooClass  
 @synthesize value;  
   
 - (void)doIt {  
      self.value = 0;  
      for (int i = 0; i < 100000; ++i) {  
           self.value = i;  
      }  
      NSLog(@"after execution: %d (%@)", self.value, [NSThread currentThread]);  
 }  
 @end  

This class has an integer property named value that is incremented 100000 times in the doIt method. At the end of doIt self.value is logged to the console with the information on which thread doIt is executed. In order to execute the doIt method, create a method called _startExperiment in your project's AppDelegate and call this method in its application:didFinishLaunchingWithOptions: method:

 - (void)_startExperiment {  
      FooClass *foo = [[FooClass alloc] init];  
      [foo doIt];  
      [foo release];  
 }  
   
 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
      // …  
      [self _startExperiment];  
      return YES;       
 }  

If we run our experiment by starting the iOS simulator (cmd + R), the _startExperiment method is called, an instance of FooClass is created on the heap and doIt is called on this instance. As expected, the console log (shift + cmd + c) shows 99999 for self.value. Nothing special so far: doIt is invoked on the main thread and it behaves as expected.

3) Thread Safety


Let us execute doIt in parallel on multiple threads:

 - (void)_startExperiment {  
      FooClass *foo = [[FooClass alloc] init];  
      dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  
     
   for (int i = 0; i < 4; ++i) {  
     dispatch_async(queue, ^{  
       [foo doIt];  
     });  
   }  
   [foo release];  
 }  

If you execute this multi-threaded version of _startExperiment, you will get an output like this (the concrete values will differ from the output that I am posting):

 after execution: 19851 (NSThread: 0x6b29bd0>{name = (null), num = 3})  
 after execution: 91396 (NSThread: 0x6b298f0>{name = (null), num = 4})  
 after execution: 99999 (NSThread: 0x6a288a0>{name = (null), num = 5})  
 after execution: 99999 (NSThread: 0x6b2a6f0>{name = (null), num = 6})  

Ouch … not on all threads self.value is 99999 as we expected (If your execution produces a correct result - on all threads self.value is 99999 - re-execute it until an incorrect result is produced. It definitely will.).

Why do not all threads produce a correct result? Well, because our code is not thread safe.

Your code is thread safe if it behaves in the same way in a multi-threaded environment as it does in a single-threaded environment.

As we observed above, the method doIt is not thread safe because it does not produce the same result in a multi-threaded environment as it does in a single-threaded environment.

But what is the reason for this behavior? As stated in the beginning, each thread has its own instruction pointer (IP) and stack but all threads share the complete heap. Since the instance of FooClass is allocated on the heap and thus shared among all threads, the threads interfere while executing doIt. Let's take a closer  look at this interference. We consider the execution of the doIt method on two threads Thread1 and Thread2:

The instruction pointer (IP) of Thread1 points to the logging of self.value but did not execute the logging yet. At this point self.value is set to 99999. Now, Thread2 continues executing doIt. Its IP points to the assignment inside the for loop. We assume that self.value is set to 91396 in the for-loop on Thread2. Uups. If Thread1 continues execution, self.value is not set to 99999 anymore but to 91396. Thread1 logs self.value and 91396 is printed. Since doIt does not prevent threads from interfering with each other while executing it, its implementation is not thread safe.

One possible way to make doIt thread safe is to synchronize its body using the @synchronized compiler directive:

 - (void)doIt {  
   @synchronized(self) {  
     self.value = 0;   
     for (int i = 0; i < 100000; ++i) {  
       self.value = i;  
     }  
     NSLog(@"after execution: %d (%@)", self.value, [NSThread currentThread]);       
   }  
 }  

Using the @synchronized directive, each thread gets exclusive access to self in doIt. Note that the threads cannot run in parallel anymore while executing doIt because the @synchronized directive covers the complete method body.

Another way of syncing access to  shared state is to use Grand Central Dispatch (GCD).

 4) How to identify not thread safe code


The experiment that I used to explain thread safety is an oversimplification of reality. In reality, you have already written your code, made some pieces run on background threads and from time to time your app is not behaving as expected. It freezes. It crashes. And you are not able to reproduce these issues.

The main cause for threading issues is shared or global state. Multiple objects access a global variable, share the same object on the heap, or write to the same persistent store. In our little experiment the state that is shared among multiple threads is self respectively self.value. The identification of shared state is quite simple in our experiment but in a real world scenario it is quite hard to go through all your classes and identify methods that manipulate shared or global state.

In order to make things easier I have written a convenient tool that identifies methods that are called from multiple threads. If I have the information which methods are called from multiple threads, I take a closer look at these methods. If such a method manipulates shared or global state, I make up a synchronization strategy for the state that is manipulated by this and other methods. In the following I will outline the core idea of this tool.

The tool consists of four classes: the instances of MultiThreadingAnalysis record calls to methods on a specific thread, the classes ThreadingTrace and MethodExecution represent the result of conducting an analysis with MultiThreadingAnalysis, and the class MultiThreadingAnalysisHook is used to hook into an object and trace all method calls to this object.



















The class MultiThreadingAnalysis offers two methods:
  • recordCallToMethod:ofClass:onThread: which records on which thread a method has been called. 
  • threadingTraceOfLastApplicationRun which should be called after the analysis has finished.

 @interface MultiThreadingAnalysis : NSObject  
   
      - (void)recordCallToMethod:(NSString*)methodName  
                ofClass:(NSString*)className  
               onThread:(NSString*)threadID;  
            
      - (ThreadingTrace*) threadingTraceOfLastApplicationRun;  
            
 @end  

The result of a multi-threading analysis is an instance of ThreadingTrace. It consists of a set of MethodExecution instances each of which represents the execution of a method on a specific thread:

 /*  
  * An instance of this class captures  
  * which methods of which classes have been  
  * called on which threads.  
  */  
 @interface ThreadingTrace : NSObject  
      /*  
       * Set of MethodExecution  
       */  
      @property (nonatomic, readonly) NSSet *methodExecutions;  
      - (void)addMethodExecution:(MethodExecution*)methodExec;  
 @end  
   
 /*  
  * An instance of this class represents a call  
  * to a method of a specific class on a thread  
  * with a specific threadID.  
  */  
 @interface MethodExecution : NSObject  
      @property (nonatomic, copy) NSString *methodName;  
      @property (nonatomic, copy) NSString *className;  
      @property (nonatomic, copy) NSString *threadID;  
 @end  

In order to make the recording of method calls as convenient as possible I am using NSProxy to hook into method calls of an object. The class MultiThreadingAnalysisHook inherits from NSProxy and intercepts all calls to a target object in its forwardInvocation: method. Before forwarding a method call to the target object it records the call by using an instance of MultiThreadingAnalysis.

 @interface MultiThreadingAnalysisHook : NSProxy  
      @property (nonatomic, strong)   id target;  
      @property (nonatomic, strong) MultiThreadingAnalysis *analysis;  
 @end  
   
 @implementation MultiThreadingAnalysisHook  
   
 -(void)forwardInvocation:(NSInvocation*)anInvocation {  
     
   [self.analysis recordCallToMethod:NSStringFromSelector([anInvocation selector])  
                    ofClass:NSStringFromClass([self.target class])  
                onThread:[NSString stringWithFormat:@"%d", [NSThread currentThread]]];  
     
   [anInvocation invokeWithTarget:self.target];  
 }  
 @end  

With the MultiThreadingAnalysisHook at your hands you can hook the multi-threading analysis into your code as proposed in the following. Create a private method _withThreadingAnalysis in the class that you want to analyze. This method creates an instance of MultiThreadingAnalysisHook and sets its target to self. In your designated initializer return the result of invoking _withThreadingAnalysis. The instance of MultiThreadingAnalysisHook will transparently wrap around self and record all calls to self without the need to change any other code outside of the class which you are analyzing.

 @implementation YourClass  
   
 - (id)init {  
      //... do init stuff here  
      return [self _withThreadingAnalysis];  
 }  
   
 - (id)_withThreadingAnalysis {  
   MultiThreadingAnalysisHook *hook =   
     [[MultiThreadingAnalysisHook alloc] init];  
   hook.target = self;  
   return hook;  
 }  
 @end  

After you have installed the MultiThreadingAnalysis via the MultiThreadingAnalysisHook you can call threadingTraceOfLastApplicationRun on MultiThreadingAnalysis to get the trace and analyze respectively visualize it. A simple way of visualizing a trace is to produce a text file from it that looks like this:

begin threading analysis for class FooClass
   method doIt (_MultiThreadAccess_)
   method init (_SingleThreadAccess_)  

If a method is accessed from multiple threads (has the tag _MultiThreadAccess_), you can take a closer look at this method to check if it manipulates shared or global state and implement a suitable thread  synchronization strategy for the manipulated state.

5) Wrap up


Your code is thread safe if it has the same behavior in a multi-threaded environment as it has in a single-threaded one. The reason for code not to be thread safe is the manipulation of shared or global state by multiple threads. Shared or global state can be a globally available persistent store, a singleton that is accessed  from multiple objects, or a global variable. The identification of methods that are accessed from multiple threads can be helpful to discover unsynchronized access to global or shared state and to devise a suitable synchronization strategy. The identification of such methods can be automated by leveraging the interception facilities of NSProxy, the recording of method calls, and the visualization of the recorded method calls.

Freitag, 20. April 2012

Wie ich im ersten Jahr mit meinem Startup nicht auf die Fresse fliege


Am Anfang jeder Gründung steht der Business Plan. Sollte er zumindest. Selten wird dieser jedoch aus eigener Motivation heraus geschrieben. Formale Vorgaben wie Mindestseitenanzahl machen das Schreiben eines Business Plans zu einem ähnlichen Vergnügen wie das Schreiben einer Abschlussarbeit. Zumal das Verfassen eines Dokumentes den Eindruck vermittelt, es handelt sich hierbei um einen bürokratischen Prozess, der zwar durch Aufteilung in einzelne Abschnitte kollaborativ und damit etwas lebendig gestaltet werden kann, aber schlussendlich nur das stumpfe Befüllen von Seiten ist. Doch das Gegenteil ist der Fall. Ein Businessplan ist der lebendige Fokus eines Unternehmens. Die einzelnen Bestandteile müssen von allen Beteiligten in enger Zusammenarbeit erdacht, verstanden und letztendlich auch zu Papier gebracht werden. Was in dieser engen Zusammenarbeit entsteht, ist kein Plan, sondern das Modell eines Unternehmens.



Ohne ein solches Modell ist ein Start-Up allem Enthusiasmus zum Trotz zum Scheitern verurteilt, denn ohne ein Business-Modell gibt es kein Gesamtziel für das Unternehmen. Ihr werdet eine Produktidee und vielleicht schon einen ersten Kunden haben, aber noch lange keine klar formulierte Strategie für die ersten Monate eures Unternehmens. Mit einem gut durchdachten Business-Modell seid ihr davor gewappnet in der Anfangsphase ins Leere zu laufen, oder anders ausgedrückt, auf die Fresse zu fliegen.

Business Plan vs. Business Modell


Was beim Verfassen eines Business-Plans am meisten ausbremst, ist die Benennung selbst. Ein Plan. Was für ein Plan? Ein Ein-, Zwei- oder vielleicht Dreijahresplan? Ein Unternehmen kann man nicht planen. Ein Unternehmen muss man leben. Nicht in den Tag hinein, aber mit klar definierten Zielen. Und Ziele sind letztendlich eine von vielen möglichen Realitäten - sie sind ein Modell der Zukunft. Und das ist es, was eigentlich bei der Erstellung eines Business Plans passiert: die Modellierung eines Unternehmens. Solch ein Unternehmensmodell (Business Model) hält fest, welche Ziele ein Unternehmen in welchem Kontext erreichen will.

Business Model Canvas


Ein Werkzeug, das uns bei orderbird besonders in der Startphase geholfen hat, Unternehmensziele und auch ihren Kontext zu formulieren, ist die Business Model Canvas (BMC).


Die BMC ist ein Werkzeug, um Business-Modelle zu erdenken und zu analysieren. Vor allem liefert sie uns aber eine gemeinsame Sprache, um Business-Modelle klar darzustellen. Diese Sprache besteht aus 9 Konzepten, die ich euch in 10 Minuten nahe bringen werde. Ich werde jedes Konzept mit praktischen Beispielen aus orderbirds Gründungsphase untermalen.

Kundensegmente (Customer segments)



Stellt euch die Frage, an wen genau ihr euer Produkt/Lösung verkaufen wollt - segmentiert den Markt. 



Gerade zu Beginn ist eure Zielgruppe nicht genau definiert. Je genauer ihr aber in der Lage seid, euren Kunden zu beschreiben, desto passendere Lösungen könnt ihr ihm verkaufen.


Für orderbird haben wir u.a. die Segmentierung nach folgenden Kriterien vorgenommen:
  • Rolle im Unternehmen: Wird ein Inhaber, Oberkellner, oder Kellner unser Produkt kaufen?
  • Art des Unternehmens: Verkaufen wir an Restaurants, Bars oder Cafes
  • Größe des Unternehmens: Wieviele Angestellte, wieviele Tische haben die?


Wertversprechen (Value Proposition)



Was wollt ihr euren Kunden verkaufen, welches Problem löst ihr?



Wenn das oder die Kundensegmente klarer umrissen sind, ist es viel leichter zu entscheiden, ob euer Unternehmen mit seiner Lösung wirklich ein Problem der Kunden lösen kann.


Für orderbird sieht das so aus:
  • Inhaber: Will die volle Kontrolle über seine Mitarbeiter, von überall aus - "Wie viel Umsatz wurde bis jetzt in Filiale 2 gemacht?"
  • Oberkellner: Will Konflikte im laufenden Betrieb schnell aufklären - "Wer hat 100 Schnitzel mit Nutella bestellt?"
  • Kellner: Will genau wissen, wieviel Geld er am Ende des Tages verdient hat - "Ich muss mir sicher sein können, dass meine Kasse stimmt."


Kanäle (Channels)



Wie kann euer Unternehmen seine potentiellen Kunden erreichen? Viel wichtiger: Wie wollen sie erreicht werden? 



Wenn ihr euch über die Erreichbarkeit eurer Kunden Gedanken macht, geht in fünf Schritten vor:
  1. Wie erregt ihr Aufmerksamkeit?
  2. Wie erlaubt ihr euren Kunden eure Lösung zu beurteilen?
  3. Wie können Kunden euer Produkt kaufen?
  4. Wie wird es geliefert?
  5. Wie betreut ihr eure Kunden nach dem Kauf?
orderbird:
  1. Gastronomie Magazine, v.a. aber Mund-zu-Mund
  2. Kostenlose Variante im App Store
  3. Online Shop (Hardware und Lizenz)
  4. Software als CD vertrieben, Hardware mit der Kutsche ;)
  5. Telefon-Support


Kundenbeziehung (Customer Relationships)  


Wie behaltet ihr einen guten draht zu euren Kunden? ... sie sollen ja wieder kommen und mehr kaufen! 

Bei den Kanälen steht v.a. die Frage im Vordergrund wie die Kunden erreicht werden wollen. Das gilt verstärkt bei der Kundenbeziehung. 

Je nach Kundensegment müsst ihr eine andere Strategie umsetzen. 

Wie wir bei orderbird gemerkt haben, erwarten fast alle Inhaber einen telefonischen Support, wenn nicht sogar Vor-Ort-Service. Kellner sind meist jünger und haben kein Problem damit, im Online-Handbuch nachzuschlagen. 

Die falsche Strategie bei der Kundenbeziehung kann euer Wertversprechen unter Umständen stark abschwächen, da sich die Kunden allein gelassen fühlen.

Einkommensströme (Revenue Streams)



Klar. Wie wollt ihr Geld machen? Nehmt aber auch hier wieder die Perspektive eurer Kunden (Segmente) ein! Für was sind sie bereit zu bezahlen?



Hier ist eine gut durchdachte Kundensegmentierung sehr hilfreich. Wenn ihr wisst, wem ihr was verkaufen wollt, könnt ihr auf jeden Fall in Erfahrung bringen, was eure potentiellen Kunden zur Zeit ausgeben. Wenn ihr wisst, was sie für ihre jetzige "Lösung" bezahlen, habt ihr einen Anhaltspunkt um herauszufinden, für was sie bereit sind zu bezahlen und wie sie bezahlen.

Es gibt verschiedene Arten von Einkommensströmen:
  • Einmaliger Verkauf
  • Verbrauchsgebunden - je mehr ein Kunde verbraucht, desto mehr bezahlt er (z.B. Datenflatrates eines Mobilfunkanbieters)
  • Abonnement - für eine z.B. monatliche Gebühr kann ein Kunde einen Dienst so oft benutzen, wie er will (z.B. Musik-Streaming-Dienste)
  • Vermietung
  • Lizenzierung - ein Kunde darf eure Technologie in seinen Produkten verwenden

Wichtig ist, dass ihr euch hier noch keine Gedanken über ein konkretes Preismodell macht. Dies ist generell eine der herausforderndsten Aufgaben und in der Anfangsphase eures Unternehmens noch schwieriger zu lösen als später.

orderbird:

Wir möchten Inhabern ein Abomodell anbieten - sie können unsere Dienste wie z.B. das Online-Reporting für x Euro so oft benutzen, wie sie möchten. Dieses Modell kommt allerdings nicht besonders gut an - obwohl es für unsere Kunden flexibler wäre, möchte sie lieber einmalig den 100fachen Betrag bezahlen, um ein Gefühl der "Sicherheit" zu haben - der Markt hat seine eigene Logik.


Bis hierhin habt ihr die wichtigsten Punkte, um einen guten Pitch auf die Bühne zu bringen. Ihr wisst genau, wem ihr was verkaufen wollt, wie ihr eure Lösung in den Markt bringt und wie ihr Geld einnehmen wollt. Die noch folgenden Konzepte der BMC setzen sich mehr mit der Umsetzung eures Business Models auseinander.

Schlüsselresourcen (Key Resources)


Was braucht ihr, um eure Lösung anzubieten, sie zu entwickeln, Kanäle zu bedienen, die Kundenbeziehung aufrecht zu erhalten?

Bei orderbird sind Schlüsselresourcen:
  • Softwareentwickler
  • PR und Sales Team
  • Hardware Supply Chain

Schlüsselaktivitäten (Key Activities)



So banal es klingen mag, aber was sind die wichtigsten Schritte, um eurer Business Modell umzusetzen? Eure Schlüsselressourcen kosten euch viel Geld. Setzt sie gewissenhaft ein.



In der täglichen Arbeit verliert man sich schnell in Kleinigkeiten. Hier hilft ein täglicher Blick auf die Liste der Schlüsselaktivitäten, um den Fokus nicht zu verlieren. Diese Liste sollte nicht mehr als 5 Einträge enthalten und sollte wöchentlich aktualisiert werden, um sich immer wieder zu fragen, was eigentlich wichtig ist.

Hier mal eine unserer Listen mit den Fragen, die wir uns stellten, ob unsere gerade ausgeführten Aktivitäten wichtig sind:
  • Reports für das Controlling entwickeln 
    (Muss das User Interface der App verbessert werden, wenn noch nicht alle wichtigen Reports eingebaut sind?)
  • Hardwarelieferanten in unser Router-Konfigurationswerkzeug einweisen 
    (Müssen wir jetzt Angebote für die Schutzhüllen einholen? Ohne unsere Einweisung kann die Hardware nicht konfiguriert und ausgeliefert werden.
  • Messeauftritt vorbereiten 
    (Müssen wir jetzt die Webseiteninternationalisierung mit der Agentur besprechen? Wir brauchen doch noch Flyer und Aufsteller.)  
  • Serveradministrator rekrutieren 
    (Müssen wir uns jetzt Serverangebote einholen und auswerten? Das kann doch der Admin machen.
  • Support-Telefonanlage konfigurieren 
    (Müssen wir uns jetzt Gedanken über die Warteschleifenansage machen? Alle Supportanrufe kommen gerade auf nur einem Telefon an.)

Schlüsselpartnerschaften (Key Partnerships)



Bei der Kundensegmentierung und der damit einhergehenden Verfeinerung des Wertversprechens werdet ihr häufig feststellen, dass ihr nicht alle Schlüsselressourcen für die Umsetzung im Unternehmen habt. Ihr braucht also Partner. Versucht alles auszulagern, das nicht von eurem Team professionell erledigt werden kann.

Bei orderbird war dies zum Beispiel der Hardwareversand. Wir hatten kein Lager und auch keine Erfahrung mit Warenwirtschaft. Also raus damit.

Cost Structure



Was kosten euch eure Schlüsselressourcen, Schlüsselaktivitäten, Kanäle etc.? Wie viel Geld benötigt ihr, um euer Business-Modell am Laufen zu halten? Können die Einkommensströme die Kosten abfangen?



An diesem Punkt wird oftmals ersichtlich, ob es realistisch ist, euer Modell umzusetzen. Wenn nicht, beginnt ihr an den verschiedenen Stellschrauben zu drehen. Für höhere Einkommensströme muss ein anderes Segment mit einem anderen Wertversprechen bedient werden. Ein anderes Segment erfordert unter Umständen einen anderen Kanal, der wiederum andere Kosten verursacht ...

Das ist die Business Model Canvas. Hier noch eine Kurzfassung:


Uns hat die BMC extrem geholfen, uns unsere Strategie für die Anfangsphase klar zu machen. 

Also, schnappt euch einen Stapel Klebezettel, druckt euch mehrere Examplare der Business Model Canvas aus, setzt euch in den Park und fangt an zu modellieren! Die BMC gibt es hier.

Alle Bilder und Information gibt es auf www.businessmodelgeneration.com.