Was viele bei der Suchmaschinenoptimierung vergessen

Wenn man Zeit und Geld in die Google Optimierung (ich sage absichtlich nur Google!) steckt, vergisst man häufig wichtige Punkte, die dem eigentlichen Wunsch nach höherer Neukundenakquise im Wege stehen.

Deshalb stellt euch folgende Fragen:

  • Kann ein Quereinsteiger innerhalb von 15 Sekunden erkennen, ob ihr ihm das bietet (Produkt, Dienstleistung, was auch immer), was er sucht? Stichwort Absprungquote!
  • Wenn er das erkennt, kann er dann auf der Seite direkt Kontakt aufnehmen (ggf. Anfrage starten oder direkt bestellen)? Stichwort Klickpfade!
  • Könnt ihr den Erfolg eurer Aktion messen?
  • Wisst ihr bereits, wie viele Neukunden ihr täglich über eure Webseite generiert?
  • Wisst ihr, wo ihr aktuell bei Google für bestimmte Suchanfragen gelistet seid? Und wie euer Ranking über Wochen hinweg verläuft?
  • Wisst ihr, ob E-Mails und Telefonanrufe über eure Webseite von Google Besuchern gekommen sind?
  • Welches Ranking nehmen eure Mitbewerber ein?
  • Habt ihr überhaupt die Chance auf den ersten 3 Seiten bei Google zu landen oder sind zu viele Big Player auf dem Markt, die die Positionen unter sich aufteilen?

 

Das sind nur einige Fragen, die nach einer Antwort verlangen und für dessen Beantwortung Vorarbeit zu leisten ist. Unkoordiniert in die Suchmaschinenoptimierung (SEO) zu investieren, ist aus finanzieller Sicht eine spekulative und vermutlich schlechte Investition.

In diesem Video erzähle ich mehr dazu:

Die erwähnten Tools gibt es hier:

 

 

Werbung

Videoserie: Alles was man über IT Berufe wissen sollte und warum 45 Jahre zu lang für den falschen Beruf sind

Alles was man über IT Berufe wissen sollte…

und warum 45 Jahre zu lang für den falschen Beruf sind!

 

Meine Motivation hinter der 3-teiligen Serie war es eine Hilfestellung bei der Berufswahl zu geben. Während Schlagworte wie „zukunftssicher“ und „lukrativ“ in nahezu jedem Artikel zu finden sind und der Konsens der ist, dass man „etwas mit IT“ studieren sollte, gebe ich euch eine etwas andere Sichtweise auf das Thema. Wie Albert Einstein schon postulierte:

Wenn du es nicht einfach erklären kannst, hast du es nicht gut genug verstanden.

 

Deshalb fasse ich den Inhalt der Serie wie folgt zusammen:

happiness

Beruf kommt von Berufung

 

Diejenigen, die ein klein wenig mehr Zeit haben, können anhand dieses 2-minütigen Einleitungsvideos entscheiden, ob die Serie für sie interessant ist:


Hier geht es zur kompletten Serie.

Wenn euch der Beitrag gefällt, dann teilt ihn und hinterlasst mir einen Kommentar. Wen ein Interview aus mehreren IT-lern unterschiedlicher Studiengänge und Hochschulen interessieren würde, der darf sich gerne melden, dann stelle ich dazu etwas auf die Beine.

Erwähnte Links in den Videos:

 

Anwender durch zielgerichtete Release Notes in die Produktentwicklung integrieren

In diesem Video zeige ich eine von vielen maßgeschneiderten Funktionen unseres Release Prozesses. Das Ziel dabei war es die Anwender noch mehr in die Produktentwicklung einzubinden.

Die langfristige Vision: Anwender bringen selbst die Anforderungen ein. Wie das genau gemeint ist und wie wir das umgesetzt haben, seht ihr im Video. Unter anderem kommen YouTrack und TeamCity zum Einsatz.

 

Über ein Rake-Skript, welches auf ein bereits existierendes YouTrack-Gem zurückgreift, sprechen wir die Rest-API an. Vielen Dank an Alexander Groß von GROSSWEBER für die Hilfe bei der Umsetzung unserer Vision.

require 'youtrack'
require 'ostruct'
module Build
class YouTrack
class View
attr_reader :issues, :by_department, :by_relevance
def initialize(issues)
@issues = issues
@by_department = department(issues)
@by_relevance = relevance(issues)
end
private
def department(issues)
create_view(issues, proc { |issue| issue.departments })
end
def relevance(issues)
create_view(issues, proc { |issue| issue.relevant_to })
end
def create_view(issues, group_by)
view = issues.inject({}) do |memo, issue|
group_by.call(issue).each do |rel|
previous_value = memo.fetch(rel, [])
new_value = previous_value << issue
memo[rel] = new_value.sort_by(&:issue_id)
end
memo
end
Hash[view.sort]
end
end
class << self
NOT_FOUND = proc { { 'value' => nil } }
def fixed_issues(from, to)
resource = client.issues
maybe_patch_unreleased_methods(resource)
query = query(from, to)
puts "Getting issue list from YouTrack using query: #{query}"
issues = resource.list(filter: query, max: 1000)
issues = force_list(issues)
transformed = transform(issues)
View.new(transformed)
end
private
def client
@client ||= Youtrack::Client.new do |c|
c.url = 'your-url'
c.login = 'your-user'
c.password = 'your-pw'
c.connect!
end
end
def maybe_patch_unreleased_methods(issues)
return if issues.respond_to?(:list)
warn 'Patching #list method'
# Get a list of issues for a search query.
#
# attributes
# filter string A query to search for issues.
# with string List of fields that should be included in the result.
# max integer Maximum number of issues to get. If not provided, only 10 issues will be returned by default.
# after integer A number of issues to skip before getting a list of issues.
#
def issues.list(attributes = {})
attributes[:max] ||= 10
get("issue?#{URI.encode_www_form(attributes)}")
end
end
def query(from, to)
"project: HECO_comWORK Fixed in build: #{from} .. #{to} Department: -KEINE #{excluded_subsystems}"
end
def excluded_subsystems
spec = ENV['RELEASE_NOTES_EXCLUDE_SUBSYSTEMS']
return unless spec
spec = spec.split(',')
return if spec.empty?
"Subsystem: #{spec.map { |s| "-{#{s}}" }.join(' ')}"
end
def force_list(issues)
issues = issues.to_hash['issueCompacts']['issue'] rescue []
([] << issues).flatten(1)
end
def transform(issues)
issues.map do |x|
field = x['field']
project = field.find { |f| f['name'] == 'projectShortName' }['value']
number = field.find { |f| f['name'] == 'numberInProject' }['value']
issue_id = "#{project}-#{number}"
subsystem = subsystem(field)
summary = field.find { |f| f['name'] == 'summary' }['value']
info = field.find(NOT_FOUND) { |f| f['name'] == 'Release Infotext' }['value']
departments = arrayify(field, 'Department')
relevant_to = arrayify(field, 'Relevant to')
OpenStruct.new(issue_id: issue_id,
subsystem: subsystem,
summary: summary,
info: info,
departments: departments,
relevant_to: relevant_to)
end
end
def subsystem(field)
value = field.find { |f| f['name'] == 'Subsystem' }['value']
return nil if value == 'No Subsystem'
value
end
def arrayify(field, key)
value = field.find(NOT_FOUND) { |f| f['name'] == key }['value']
return [] if value.nil?
([value]).flatten.sort
end
end
end
end
view raw youtrack.rb hosted with ❤ by GitHub

Wer weitere Einblicke in unseren Prozess bekommen möchte, der kann mir dazu einen Kommentar hinterlassen.


require 'youtrack'
require 'ostruct'
module Build
class YouTrack
class View
attr_reader :issues, :by_department, :by_relevance
def initialize(issues)
@issues = issues
@by_department = department(issues)
@by_relevance = relevance(issues)
end
private
def department(issues)
create_view(issues, proc { |issue| issue.departments })
end
def relevance(issues)
create_view(issues, proc { |issue| issue.relevant_to })
end
def create_view(issues, group_by)
view = issues.inject({}) do |memo, issue|
group_by.call(issue).each do |rel|
previous_value = memo.fetch(rel, [])
new_value = previous_value << issue
memo[rel] = new_value.sort_by(&:issue_id)
end
memo
end
Hash[view.sort]
end
end
class << self
NOT_FOUND = proc { { 'value' => nil } }
def fixed_issues(from, to)
resource = client.issues
maybe_patch_unreleased_methods(resource)
query = query(from, to)
puts "Getting issue list from YouTrack using query: #{query}"
issues = resource.list(filter: query, max: 1000)
issues = force_list(issues)
transformed = transform(issues)
View.new(transformed)
end
private
def client
@client ||= Youtrack::Client.new do |c|
c.url = 'your-url'
c.login = 'your-user'
c.password = 'your-pw'
c.connect!
end
end
def maybe_patch_unreleased_methods(issues)
return if issues.respond_to?(:list)
warn 'Patching #list method'
# Get a list of issues for a search query.
#
# attributes
# filter string A query to search for issues.
# with string List of fields that should be included in the result.
# max integer Maximum number of issues to get. If not provided, only 10 issues will be returned by default.
# after integer A number of issues to skip before getting a list of issues.
#
def issues.list(attributes = {})
attributes[:max] ||= 10
get("issue?#{URI.encode_www_form(attributes)}")
end
end
def query(from, to)
"project: HECO_comWORK Fixed in build: #{from} .. #{to} Department: -KEINE #{excluded_subsystems}"
end
def excluded_subsystems
spec = ENV['RELEASE_NOTES_EXCLUDE_SUBSYSTEMS']
return unless spec
spec = spec.split(',')
return if spec.empty?
"Subsystem: #{spec.map { |s| "-{#{s}}" }.join(' ')}"
end
def force_list(issues)
issues = issues.to_hash['issueCompacts']['issue'] rescue []
([] << issues).flatten(1)
end
def transform(issues)
issues.map do |x|
field = x['field']
project = field.find { |f| f['name'] == 'projectShortName' }['value']
number = field.find { |f| f['name'] == 'numberInProject' }['value']
issue_id = "#{project}#{number}"
subsystem = subsystem(field)
summary = field.find { |f| f['name'] == 'summary' }['value']
info = field.find(NOT_FOUND) { |f| f['name'] == 'Release Infotext' }['value']
departments = arrayify(field, 'Department')
relevant_to = arrayify(field, 'Relevant to')
OpenStruct.new(issue_id: issue_id,
subsystem: subsystem,
summary: summary,
info: info,
departments: departments,
relevant_to: relevant_to)
end
end
def subsystem(field)
value = field.find { |f| f['name'] == 'Subsystem' }['value']
return nil if value == 'No Subsystem'
value
end
def arrayify(field, key)
value = field.find(NOT_FOUND) { |f| f['name'] == key }['value']
return [] if value.nil?
([value]).flatten.sort
end
end
end
end

view raw

youtrack.rb

hosted with ❤ by GitHub


require 'youtrack'
require 'ostruct'
module Build
class YouTrack
class View
attr_reader :issues, :by_department, :by_relevance
def initialize(issues)
@issues = issues
@by_department = department(issues)
@by_relevance = relevance(issues)
end
private
def department(issues)
create_view(issues, proc { |issue| issue.departments })
end
def relevance(issues)
create_view(issues, proc { |issue| issue.relevant_to })
end
def create_view(issues, group_by)
view = issues.inject({}) do |memo, issue|
group_by.call(issue).each do |rel|
previous_value = memo.fetch(rel, [])
new_value = previous_value << issue
memo[rel] = new_value.sort_by(&:issue_id)
end
memo
end
Hash[view.sort]
end
end
class << self
NOT_FOUND = proc { { 'value' => nil } }
def fixed_issues(from, to)
resource = client.issues
maybe_patch_unreleased_methods(resource)
query = query(from, to)
puts "Getting issue list from YouTrack using query: #{query}"
issues = resource.list(filter: query, max: 1000)
issues = force_list(issues)
transformed = transform(issues)
View.new(transformed)
end
private
def client
@client ||= Youtrack::Client.new do |c|
c.url = 'your-url'
c.login = 'your-user'
c.password = 'your-pw'
c.connect!
end
end
def maybe_patch_unreleased_methods(issues)
return if issues.respond_to?(:list)
warn 'Patching #list method'
# Get a list of issues for a search query.
#
# attributes
# filter string A query to search for issues.
# with string List of fields that should be included in the result.
# max integer Maximum number of issues to get. If not provided, only 10 issues will be returned by default.
# after integer A number of issues to skip before getting a list of issues.
#
def issues.list(attributes = {})
attributes[:max] ||= 10
get("issue?#{URI.encode_www_form(attributes)}")
end
end
def query(from, to)
"project: HECO_comWORK Fixed in build: #{from} .. #{to} Department: -KEINE #{excluded_subsystems}"
end
def excluded_subsystems
spec = ENV['RELEASE_NOTES_EXCLUDE_SUBSYSTEMS']
return unless spec
spec = spec.split(',')
return if spec.empty?
"Subsystem: #{spec.map { |s| "-{#{s}}" }.join(' ')}"
end
def force_list(issues)
issues = issues.to_hash['issueCompacts']['issue'] rescue []
([] << issues).flatten(1)
end
def transform(issues)
issues.map do |x|
field = x['field']
project = field.find { |f| f['name'] == 'projectShortName' }['value']
number = field.find { |f| f['name'] == 'numberInProject' }['value']
issue_id = "#{project}#{number}"
subsystem = subsystem(field)
summary = field.find { |f| f['name'] == 'summary' }['value']
info = field.find(NOT_FOUND) { |f| f['name'] == 'Release Infotext' }['value']
departments = arrayify(field, 'Department')
relevant_to = arrayify(field, 'Relevant to')
OpenStruct.new(issue_id: issue_id,
subsystem: subsystem,
summary: summary,
info: info,
departments: departments,
relevant_to: relevant_to)
end
end
def subsystem(field)
value = field.find { |f| f['name'] == 'Subsystem' }['value']
return nil if value == 'No Subsystem'
value
end
def arrayify(field, key)
value = field.find(NOT_FOUND) { |f| f['name'] == key }['value']
return [] if value.nil?
([value]).flatten.sort
end
end
end
end

view raw

youtrack.rb

hosted with ❤ by GitHub

AdBlock ist tot, lang lebe uBlock

Wer sich wie ich über die vielen Einträge in der Whitelist von Adblock ärgert (Quelle1, Quelle2) und ständig von Werbung zugemüllt wird, dem sei folgende Lösung ans Herz gelegt:

uBlock, das es für Chrome und Firefox gibt. In den Einstellungen müsst ihr noch diesen Haken setzen

image

Danach folgt ihr dieser Anleitung, damit ihr nicht von Seiten ausgeschlossen werdet, die uBlock erkennen.

Voila, endlich wieder Werbefrei. Funktioniert auch bei vielen Videos.

Wir suchen Büros in Karlsruhe und Durlach für unsere IT Firma

Für unsere IT-Consulting Firma (Ausgliederung der IT Abteilung) suchen wir in Karlsruhe oder Durlach nach Büroräumen. Nachfolgend unsere Wunschliste. Wenn jemand jemanden kennt, der jemanden kennt, dann würde ich den auch gerne kennen lernen :). Oder kurz: Für Hinweise wäre ich dankbar.

Dabei spielt es keine Rolle, ob es sich um einen Neubau handelt, bei welchem wir noch mitgestalten können, oder ob es fertig eingerichtet ist und sich nichts mehr ändern lässt. Wir haben nur sehr selten Kundenbesuch und benötigen keinen Empfangsbereich. Schön wäre Trockenbau, sodass wir ggf. die Raumaufteilung anpassen können.

must-haves:

  • Einzug bis spätestens Mitte 2016
  • Lage: Karlsruhe Innenstadt, Umkreis Karlsruhe Hauptbahnhof (Südstadt), Umkreis Karlsruhe Durlacher Tor / Scheck-In, Durlach Innenstadt oder Durlach Richtung Karlsruhe
  • S-Bahn-Anbindung in 5-10 Gehminuten Entfernung
  • Größe mind. 160m² bis max. 250m² und Platz für mind. 5 Arbeitsplätze
  • 1 großer Raum für Schulungen (ca. 40m² und größer)
  • Einbauküche oder die Möglichkeit eine Küche zu verbauen
  • Gute Internetanbindung (vorzugsweise von der Telekom)


nice-to-have:

  • Idealerweise mit festen Parkplätzen oder mit guten Parkmöglichkeiten
  • Gute Verkabelung (CAT6 oder CAT7) vorhanden oder Einbau möglich
  • Dusche bereits vorhanden oder Einbau möglich

 

Kontakt einfach über einen meiner Kanäle oder unter +497232-3655-555.

 

Business Analysten entwickeln fachliche Lösungen, Entwickler technische! Oder?

Die Grenze zwischen den Rollen im Entwicklungsprozess sind fließend. In meinem vorherigen Beitrag habe ich erläutert, wen ich mit welche Rolle betrauen würde und wie sich dadurch die Produktentwicklung um das 100-fache beschleunigen lässt.

Wer kann sich wie an der Lösung beteiligen?

Wer kann sich wie an der Lösung beteiligen?

In diesem Beitrag möchte ich meine Sicht darauf geben, bis zu welcher Stelle der Product Owner gefragt ist und wann die Arbeit des Entwicklers beginnt. Dazu greife ich das Beispiel aus diesem Video auf:

 5*3 = 15

Stellen wir uns den Entwickler als Schüler in einer Matheklasse vor, die Multiplizieren lernen sollen. Der Business Analyst (BA) ist dabei der Lehrer, welcher den Schülern erklärt wie die Multiplikation funktioniert. Lediglich das Ergebnis zu nennen kann bei sehr trivialen Prozessen möglich sein. Da die wenigsten Prozesse in Unternehmen trivial sind, gehen wir davon aus, dass wir einer Erklärung bedürfen. Und genau an dieser Stelle scheiden sich häufig die Geister: In welche Tiefe muss der BA in das Problem einstigen und wie weit ins Detail bei dem Lösungsansatz gehen?

Klar ist: Der Lösungsansatz muss vom BA kommen, denn nur er weiß, wie er den Prozess gerne hätte bzw. wie er korrekt ist. Im obigen Beispiel muss der Lehrer den Schülern sagen, dass sich eine Multiplikation in eine Summe umformen lässt. Das kennen die Schüler bereits. Der Lehrer würde ihnen also sagen:

5*3 = 5+5+5 = 15

Leider ist das falsch. Nicht das Ergebnis, aber der Rechenweg.

5*3 = 5+5+5 = 15

Denn der korrekte Rechenweg lautet:

5*3 = 3+3+3+3+3 = 15

Leider reicht es bei Prozessen nur selten, wenn lediglich das Ergebnis korrekt ist, denn die Zwischenergebnisse können auch weiterverwendet werden. Außerdem ist nicht gesagt, dass für alle möglichen Werte das Ergebnis immer stimmt.

Wir waren uns einig, dass der Rechenweg vom BA kommen muss. Macht es dann Sinn, dass der Entwickler diesen validieren und ggf. zig Testrechnungen durchführen muss, um die Richtigkeit zu gewährleisten? Würden das die Schüler der imaginären Schulklasse machen? Können diese überhaupt alle etwaige Abzweigungen/Konstellationen kennen. Was wäre, wenn wir von irrationalen Zahlen sprechen würden? Die sind den Schülern noch gar nicht bekannt. Aber wie sollten sie dann eine Testrechnung mit selbigen machen? Wenn als nächstes auf dem Lehrplan die Division stünde, welche in eine Multiplikation umgeformt werden kann, wären die Schüler dann in der Lage den Rechenweg dahingehend zu validieren, dass er später auch bei Divisionen funktioniert?

Ich bin der Meinung, dass dem nicht so ist und daher der BA sich entsprechend darum kümmern muss. Dagegen spricht ebenfalls, dass es im Sender-Empfänger-Modell immer zu Problemen kommen kann. Wenn ich beim Schach von einem Spielfeld rede, meine ich dann das gesamte Brett oder eines der 64 Felder? Je früher es dabei zu Missverständnissen kommt, desto weiter bewegt man sich von der Lösung weg. Denn wenn der BA nur kontrolliert, ob das Ergebnis 15 ist, dann könnte im Untergrund auch einfach 5+10 gerechnet worden sein.

Selbst kleine Ungenauigkeiten können in der Praxis grobe Probleme machen. Ob ich einen Rabatt entweder auf jede einzelne Position einer Rechnung anwende und dann summiere oder ob ich den Rabatt auf gesamte Rechnung anwende und dann auf die einzelnen Positionen verteile, ist ein großer Unterschied. In bestimmten Fällen können so Rundungsfehler entstehen, die am Schluss das Ergebnis verändern. Wenn ich zuerst 10% abziehe und dann wieder 10% dazu rechne, dann kommt eben nicht der ursprüngliche Betrag heraus.

Mit diesen Details müssen sich aus meiner Sicht die Business Analysten beschäftigen. In technische Lösungen einzusteigen, verlangt niemand. Genauso wenig erwarte ich, dass alles immer zu 100% durchdacht werden kann. Ich schließe auch nicht aus, dass die Entwickler Vorschläge für bessere Lösungen geben. Aber wenn es um die fachliche Problemanalyse und das Entwickeln eines Lösungsansatzes geht, dann ist das die Kernaufgabe der BAs.

Wie seht ihr das? Sind bei euch die Aufgaben klar getrennt? Funktioniert das bei euch? Oder übernehmen bei euch die Entwickler die Rolle Business Analysten?

Wie mittelständische Unternehmen ihre Produktentwicklung um das 100-fache beschleunigen

Vorweg: Die Zahl 100 ist frei erfunden, aber jetzt, wo du schon mal da bist, kannst du trotzdem weiterlesen und am Ende gerne einen Kommentar hinterlassen.

Rollen bei der Softwareentwicklung

Rollen bei der Softwareentwicklung

Während Konzerne ganze Teams von Business Analysten mit entsprechendem akademischem Background haben, sind kleine und mittelständische Unternehmen (KMUs) weniger breit aufgestellt. Das trifft genauso auf die Größe des Entwicklerteams zu: Dedizierte Software-Architekten und Development Leads gibt es nur selten. Das rechte Bild zeigt einige der Rollen im Entwicklungsprozess von Software (aus diesem hervorragenden Video von Pluralsight entnommen). Deshalb gilt es zu analysieren, wer im Unternehmen welche Kompetenzen besitzt und wo es zu Engpässen kommt. Die Grenzen der Rollenübergänge sind aufgrund der fehlenden dedizierten Rollenbesetzung fließend und werden deshalb häufig von mehreren Personen übernommen.

Das trifft speziell auf die Rolle des Business Analysten zu. Während Wikipedia eine lange Liste von Aufgaben für diesen definiert, will ich meine Sicht – oder besser meine Vision – darlegen, auf welchen Personenkreis die Aufgaben in KMUs aufgeteilt werden müssen. Denn wenn diese Rolle im Unternehmen sinnvoll implementiert wird, ergibt sich ein gewaltiges Optimierungspotential. Generell muss das aber unternehmensspezifisch nach Kompetenzen und Verfügbarkeiten der Mitarbeiter geregelt werden. Diese gilt es kontinuierlich weiterzuentwickeln.

Zukunft des Anwenders

Fachexperten (in der Grafik Subject Matter Expert genannt) sind die eigentlichen Anwender des jeweiligen Geschäftsprozesses. Will man also wissen, wie das Versenden eines Packstückes abläuft und wo es dabei zu Problemen kommt, dann wäre der Lagerist der richtige Ansprechpartner. Deshalb sollte er es auch sein, der den Prozess im Unternehmenswiki festhält. Ein Wiki deshalb, weil es sich einfach nutzen lässt und einige wenige Regeln genügen, um es erfolgreich mit Inhalten zu füllen. Außerdem ist es die Grundlage, um neben dem Prozess Know How weiteres Inselwissen zu erfassen.

Zukunft des Product Owners

Die Koordination, den Überblick über Domänengrenzen hinweg, die Konsolidierung der Informationen und das Überführen von Anwenderwünschen siedle ich beim Produktverantwortlichen (Product Owner bei Scrum) an. Mit steigender Kompetenz und mit steigendem Wissen der Anwender können selbige immer mehr Verantwortung und Aufgaben übernehmen, z.B. das Formulieren der eigenen Wünsche in das Issue Tracking System (Backlog in Scrum). Der Product Owner wird dann stärker zum Koordinator, der das Big Picture und die Vision vorantreibt, der eher in Innovationen statt Evolutionen denkt und der Anforderungen (Achtung: Wunsch != Anforderung) noch besser herausarbeitet. In dem Zuge sind Akzeptanzkriterien zu nennen. Eines könnte lauten:

Wenn eine Rechnung abgeschlossen wird,

  • dann lässt sie sich nicht mehr verändern
  • dann wird sie automatisch an die Rechnungsabteilung geschickt
  • dann wird die Marge es Auftrags berechnet
Zukunft des Entwicklers

Und zu guter Letzt kommen wir noch auf den Entwickler zu sprechen: Je weniger er in die Ausarbeitung von Anforderungen, fachlichen Lösungsansätzen und Modellierungen stecken muss, desto mehr Zeit kann er in gute Softwarearchitektur stecken. Und eine gute Architektur ist der Schlüssel für gute, adaptive und skalierbare Produkte. Die Grenze, wo die Aufgaben des Product Owners aufhören und die des Entwickler anfangen, ziehe ich an der Stelle, wo es einer entsprechenden Ausbildung bedarf – und sei es nur 1. Semester Informatik im Rahmen des BWL-Studiums. Ob der Datentyp Integer werden soll oder ob eine Enum die bessere Wahl für eine Auswahlliste ist, das entscheidet der Entwickler. Bei Fragen nach gültigen Wertebereichen, z.B. ob als Gewicht für einen Artikel 0 Kg zulässig sind, das kann der Produktverantwortliche mit steigender Kompetenz früher oder später gleich mitgeben. Hier bedarf es aber immer der sorgfältigen Prüfung des Entwicklers, dem sich solche Fragen naturgemäß eher erschließen. Hingegen ist der Product Owner immer für das Entwerfen der fachlichen Lösungsansätze verantwortlich, denn nur er hat den Überblick über den Geschäftsprozess und wie dieser mit anderen Prozessen interagiert. Für ein konkretes Beispiel kannst du diesen Beitrag lesen.

Fazit/Vision

Anwender sollte man in den Produktentwicklungsprozess einbinden. Mit steigender Erfahrung können sie mehr Aufgaben übernehmen und helfen, die Entwicklung zu beschleunigen und das Produkt noch besser zu machen. Transparenz, größere Akzeptanz, besseres Verständnis und die Reduzierung von Inselwissen sind nur einige wichtige Nebeneffekte. Ein Feature, sei es noch so gut, welches aufgrund von Ablehnung nicht genutzt wird, ist wertlos. Ein Prozess, egal wie gut durchdacht er ist, um den aber herumgearbeitet wird, produziert mehr Probleme als dass er löst.

Im Gegenzug kann der Produktverantwortliche mehr Zeit in Innovationen und bessere Anforderungen stecken, die zu besserer Softwarearchitektur und niedrigeren Entwicklungskosten führen. Das Ergebnis ist eine schnellere Entwicklung eines passgenaueren Produkts mit weniger Fehlern und höherer Qualität.

Der Entwickler wiederrum kann sich auf eine solide Infrastruktur konzentrieren, die zum Einen schnelle und einfache Anpassungen ermöglicht, zum Anderen entsteht Zeit für das Automatisieren von regelmäßigen Abläufen. Durch automatisierte Tests (durch gute Akzeptanzkriterien) lässt sich das Gros der Arbeit der Tester übernehmen (siehe Rolle in der Grafik oben). Ein Continuous Deployment System macht händisches Deployment überflüssig. Trainings reduzieren sich auf ein Minimum, weil die Fachabteilung von Anfang an in die Prozessumsetzung eingebunden wurde.

Wie haltet ihr das bei euch? Schreibt mir eure Erfahrungen in die Kommentare. Wie weit die Transformation bei heco fortgeschritten ist, erzähle ich in diesem Beitrag (Link folgt noch).

Wenn es ein bisschen mehr sein darf – Zusatzleistungen für IT-ler

Die Karrierebibel nennt in ihrem Beitrag die Top 10 Benefits der Arbeitgeber. Erwartungsgemäß sind flexible Arbeitszeiten und Home Office ganz oben. Der Firmenwagen rangiert hingegen nur noch auf Platz 6.

Neben diesen – in der Regel bekannten und häufig angebotenen – Zusatzleistungen würde ich gerne wissen, was euch abseits vom Mainstream reizen würde. Dazu ein paar Gedanken meinerseits:

  • Eine Putzfrau für die eigene Wohnung
  • 2 extra Urlaubstage nach 10-jähriger Firmenzugehörigkeit (z.B. 32 statt 30)
  • Zusatzkrankenversicherung (z.B. für Heilpraktiker, Zähne oder Brillen)
  • Freistellung und Übernahme der Kosten für eure Fachvorträge, Community Touren oder Vorlesungen (sprich ihr betätigt euch nebenher als Referent und die Firma unterstützt euch voll dabei)
  • Regelmäßige Firmenausflüge (z.B. mal an den Bodensee)
  • Jahresticket für den Nahverkehr (dann kann es freitags direkt zum TGIF-Bierchen gehen)
  • Provision bei Vermittlung von Kunden oder neuen Mitarbeitern (bringt allen etwas)
  • Übernahme der Kosten fürs Fitnessstudio
  • Home Office Ausstattung (abseits vom Mainstream z.B. höhenverstellbare Schreibtische oder W-LAN Router)
  • Kindle / Tablet
  • Unterstützung beim Hobby (beim Marathon-Läufer z.B. Laufschuhe, Startgebühr und Shirt)
  • Kostenfreie Getränke
  • Tischkicker
  • Mitnahme von Urlaub ins Folgejahr
  • Auszahlung Urlaubstage

Ich bin gespannt, was euch einfällt. In ein paar Tagen will ich mit den Vorschlägen eine Umfrage über Facebook / Twitter starten, um zu schauen, welche davon vielleicht bei uns zum Einsatz kommen sollten.

In meinem vorherigen Beitrag habe ich zur Diskussion über die Anforderungen an ein modernes Büro angeregt.

Was IT-ler von einem modernen Büro erwarten

Welche Anforderungen habt ihr als IT-ler an eure Büros?

Schreibt mir in die Kommentare was immer euch wichtig ist. Besonders interessiert mich wie wichtig die Location für euch ist.

  • Wollt ihr z.B. keinesfalls in einem Großraumbüro arbeiten?
  • Ist euch eine gute S-Bahn-Anbindung wichtig?
  • Sollten feste Parkplätze bereitgestellt werden, damit ihr euch die morgendliche Suche spart?
  • Sind dedizierte Rückzugsräume wichtig?
  • Muss es Mitten in der City sein, damit ihr direkt nach der Arbeit z.B. ins Fitnessstudio oder in der Mittagspause zum Veganer um die Ecke gehen könnt?
  • Was sind akzeptable Fahrzeiten zum Büro? 15 Minuten ja, 30 Minuten nein?
  • Wäre euch der Stadtrand lieber, sodass ihr etwas Grün vor dem Fenster habt? Eventuell mit Balkon?
  • Oder eher ein nahe gelegener Vorort, wohin es sich bequem mit dem Auto (ohne zig Ampeln) fahren lässt?
  • Ist eine Einbauküche Pflicht?
  • Wäre eine Dusche hilfreich, damit ihr morgens zum Büro joggen oder mit dem Fahrrad fahren könnt?
  • Wie sehr beeinflusst die Location eure Entscheidung bei der Arbeitgeberwahl?

Das meinen vier IT-ler aus Karlsruhe:

  • Also ich würde Arbeitgeber im Umkreis von 15 Minuten vom Stadtzentrum gut finden. Die Location fließt zu 1/3 in meine Auswahl ein.
  • Ich denke die Örtlichkeit ist schon recht wichtig. Eine weite Fahrstrecke will keiner auf sich nehmen, da muss es schon ein Bomben-Job sein, dass man länger als 30min Fahrzeit in Kauf nimmt. Ich weiß wovon ich rede ich fahre momentan jeden morgen 35 Minuten nach Walldorf. Job und Team passen aber, von daher mache ich es auch. Außerdem müssen sich auch die Spritkosten rechnen. Ist also schon eine Überlegung. Ich würde kein Office zu weit in der Pampa suchen.
  • Mit viel Raum zum Atmen, Großraum Büros aber überall auch Rückzugsmöglichkeiten zum Tele/Skype. Ich kann dir nur sagen, dass es im agilen Umfeld mega wichtig ist, wenn es keine Wände zwischen Teamkollegen und dem Teamspace gibt.
  • ich mag es auch gerne außerhalb, wenn man gut mit dem Auto hinkommt, auf dem Weg nicht im Stau steht und einen Parkplatz bekommt. Der Stau lässt sich ja durch Gleitzeit umgehen[…]. Für mich wäre z.B. ein Büro in der Innenstadt ohne Parkplatz eher ein NoGo.

Im nächsten Beitrag werde ich nach den Benefits fragen, die euch ein Arbeitgeber bieten muss. Was haltet ihr z.B. von 2 extra Urlaubstagen nach 10 Jahren Firmenzugehörigkeit? Oder einer vom Arbeitgeber gesponserten Putzfrau? Hier könnt ihr eure Meinung posten.

Interview zu AngularJS mit Gregor Woiwode und Johannes Hoppe am Developer Open Space 2015

Wir nehmen wie immer gerne Feedback mit. Gregor und Johannes könnt ihr über die in den Show Notes verlinkten Webseiten kontaktieren. Ich bin sicher, dass Input für das Buch gerne aufgenommen und ggf. eingefügt wird.

Umfrage zu neuem Firmenlogo

Entscheidet mit über das Logo für unsere neue IT Firma „co IT“ in Karlsruhe. Hier geht es zur Umfrage auf 99 Designs:

8 Designs stehen zur Auswahl für die co IT.

8 Designs stehen zur Auswahl für die co IT.

Docker Session am NET Open Space Süd 2015

Aus aktuellem Anlass (Workshop am devspace2015) das Video zu Docker, in welchem Alexander Zeitler uns in einer Live Demo das Ökosystem vorstellt.

Alexander Zeitler stellt Docker vor.

Durch Klicken gelangt ihr zum Video.

Open Closed Principle mit 2 Zeilen Code

In meinem Video zu 60 Minuten mit der Pfadfinderregel war ich noch die Lösung zu Castle.Windsor schuldig. In diesem Webcast zeige ich wie die CollectionResolver-Funktionalität genutzt werden kann, um nachträglich hinzugefügte Implementierungen automatisch im Container zu registrieren.

Dadurch kann das OCP vollständig eingehalten werden, da lediglich eine neue Klasse hinzugefügt werden und der restliche Code nicht angefasst werden muss. Den Code habe ich hier zur Verfügung gestellt. Fragen und Feedback einfach in die Kommentare.

public class Installer : IWindsorInstaller
{
/// <summary>
/// Performs the installation in the <see cref="T:Castle.Windsor.IWindsorContainer" />.
/// </summary>
/// <param name="container">The container.</param>
/// <param name="store">The configuration store.</param>
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Kernel.Resolver.AddSubResolver(new Castle.MicroKernel.Resolvers.SpecializedResolvers.CollectionResolver(container.Kernel));
container.Register(Components().ToArray());
}
private static IEnumerable<IRegistration> Components()
{
//have a look at https://github.com/castleproject/Windsor/blob/master/docs/registering-components-by-conventions.md
yield return Classes //non abstract classes; you could also use Types.* for more choices
.FromThisAssembly() //should be clear
.IncludeNonPublicTypes() //since my implementations are internal, only the interface is public
.BasedOn<IFoo>() //every class that implements this interface
.WithService.Base() //also possible: .WithServiceFromInterface()
.LifestyleTransient();
yield return Component
.For<IBar>()
.ImplementedBy<Bar>()
.LifestyleTransient();
}
}

Durch Klicken auf das Bild geht es zum Video

Durch Klicken auf das Bild geht es zum Video

WordPress, TYPO3 CMS, TYPO3 NEOS – Anforderungen an ein gutes Content Management System

Die Anforderungsanalyse ist das A und O in Entscheidungsprozessen über Software-Systeme. In einem Praxisbeispiel zeige ich euch unser Ergebnis bei der Auswahl des neuen Content Management Systems. Dabei erkläre ich, was funktionale und nicht-funktionale Anforderungen sind, mit welchen Prioritäten wir diese unterscheiden und nenne Do’s & Don’ts von evaluierbaren Anforderungen.

Durch Klicken auf das Bild geht es zum YouTube Video

Durch Klicken auf das Bild geht es zum YouTube Video

Webseiten Baukästen können teuer werden

Oder doch nicht? Das könnt ihr erst bewerten, wenn ihr ein Mindestmaß an Hirnschmalz reingesteckt habt. Gerade kleine und mittelständische Unternehmen (KMUs), die vielleicht auch nur wenige Produkte im Portfolio haben, gehen zu schnell an die Umsetzung und verbrennen dadurch mehr Geld als notwendig. In dem Video gebe anhand eines Praxisbeispieles ein paar Fragen mit, die ihr euch stellen könnt. Das sind z.B.

  • Anbindung bestehender Systeme (ERP zur Bestandsanzeige)
  • Mehrsprachigkeit
  • Tracking
  • Google-Optimierung
  • Online Shopping
  • Kundengruppen / Personas
  • Inhaltstypen (Text, Bild, Tabellen, Videos, interaktive Elemente)
  • Redakteure bzw. wer pflegt die Inhalte
  • Wie oft ändern sich die Inhalte
  • Mobile-Optimierung
  • und einige mehr

Das Video soll euch nur ein paar anfängliche Ideen geben. Es gibt noch viele weitere Punkte und am Ende steht eine Anforderungsanalyse wie >hier< (Link folgt später).

Hier geht es zum YouTube Video.

Durch Klicken auf das Bild geht es zum Video

Die großen 4: Pfadfinderregel, Wirtschaftlichkeit, Clean Code, SOLID Principles

Was ist damit gemeint? Gemäß der Pfadfinderregel soll ein Entwickler Code immer besser hinterlassen, als er ihn vorgefunden hat. Clean Code oder guter Code ist häufig dann erreicht, wenn das Mindestmaß an essentiellen Code Prinzipien umgesetzt ist. Das sind die sogenannten SOLID Principles. Jedoch ist guter Code kein Selbstzweck, sondern dient dem größeren Ziel der Wirtschaftlichkeit.

Im folgenden Video zeige ich an einem Praxisbeispiel, wie ich bei einem bestehendem, eher unwichtigem Projekt vorgegangen bin. Timeboxed in 1h so viel refaktorisieren und den Code verbessern wie möglich. Dabei gehe ich auf Prinzipien wie DRY und OCP ein und zeige Techniken wie DI, sowie Tools wie den IoC Container Castle Windsor.

Feedback nehme ich wie immer gerne mit. Wenn ihr mehr von solchen Videos sehen wollt, schreibt mir das in die Kommentare, damit ich weiß: Hier lohnt es sich mehr zu machen.

Zum YouTube Video

Durch Klicken auf das Bild geht es zum Video

Postalische Werbung von Xing deaktivieren

Wer keine Post mehr von Xing erhalten will, muss die Option in seinen Einstellungen deaktivieren, da diese automatisch aktiviert ist. Ruft dazu diesen Link auf oder geht – eingeloggt in eurem Profil – rechts oben auf „Einstellungen, Rechnungen & Konten“ (Zahnrad), dann auf das Reiter Benachrichtigungen und ganz unten gibt es die Option

An meine im Profil hinterlegten Adressen

unter dem Oberpunkt

Angebote und Informationen per Post

welche ihr deaktivieren müsst (siehe Screenshot). Ich empfehle euch generell regelmäßig in die Einstellungen eurer Social Media Konten wie Facebook, Twitter und Co. zu schauen, da neue Einstellungen häufig so voreingestellt sind, dass sie sich negativ auf die Privatsphäre und den Datenschutz auswirken.

Beispielsweise könnt ihr in diesem Beitrag nachschauen, wie ihr auf Facebook eure Daten für Werbetreibende sperrt. Über den Tag Datenschutz findet ihr weitere Hilfestellungen unterschiedlichster Art.

Wie fachlich klare Konzepte technische Probleme lösen

Nachdem ich im vorherigen Beitrag Beispiele zur Abgrenzung des fachlichen Konzepts Kunde gegeben habe, möchte ich in dem folgenden Video erklären, wie die Fachabteilung zu guter Software beitragen kann. Denn wenn fachliche Konzept klar abgegrenzt werden, fallen viele technische Probleme automatisch weg.

Der Klick aufs Bild führt zu dem Video in meinem YouTube Channel. Unten auf dem Zahnrad könnt ihr die Auflösung hochsetzen.

Video mit der Erklärung für die Fachabteilung woher die technischen Probleme bei der Vermengungen von fachlichen Konzepten kommen.

Video mit der Erklärung für die Fachabteilung woher die technischen Probleme bei der Vermengungen von fachlichen Konzepten kommen.

Das Konzept Kunde gibt es nicht

man listen

Die Entwickler müssen genau hinhören, was mit manchen Begriffen gemeint ist. (Quelle: Fotolia)

Im vorherigen Artikel habe ich erläutert, wie der Domänenbegriff Kunde in unterschiedlichen Bedeutungen verwendet wird. In diesem Post mache ich einige Vorschläge, welche zeigen, wie es sich besser machen lässt.

Der Kunde im Verkauf ist die Person, die meine Produkte kauft. Er ist also der Käufer.

Im Support ist der Kunde derjenige, der meine Produkte bedient und sich bei Fragen zur Bedienung an den Support wendet. Da könnten vielleicht Anwender oder Nutzer als Begriffe in Frage kommen.

Im Rechnungswesen ist der Kunde derjenige, der mir Geld für meine Produkte schuldet und die Schuld dann hoffentlich begleicht. Schuld => Debit => Debitor. Oder alternativ Kontoinhaber. Das wiederum könnte aber zur Verwechslung mit den Lieferanten führen, die natürlich auch Kontoinhaber sind. Also nehmen wir besser Debitor.

Im Versand oder im Lager geht es darum die Produkte an einen Empfänger auszuliefern. Wir benötigen die Adresse, um das Paket, das die Ware erhält, zu adressieren. Also Empfänger, Adressat, Warenempfänger – man hat die freie Auswahl.

Das Marketing hat unter anderem die Ziele, die Neukundenakquise mit Werbemaßnahmen anzukurbeln, gleichzeitig aber die Kundenbindung zu festigen. Also wie wäre es mit Neukunde und Bestandskunde. Alternativ potentieller Kunde oder – für manche Branchen denkbar – Kandidat.

Fazit

Es muss nicht immer schwer sein gute Domänenbegriffe zu finden, die klar ausdrücken, worum es sich bei dem Konzept handelt. Oftmals genügt es sich die Domäne, in der der Begriff verwendet wird, anzuschauen und zu umschreiben, was der Begriff ausdrücken soll. Mit der Erfahrung wird das für den Fachexperten ganz selbstverständlich und ihm springen förmlich schlechte Benennungen ins Gesicht (schon mal über das Konzept der ‚Benutzer‘ nachgedacht?).

In meinem nächsten Artikel kommen wir zu der spannenden Frage, woher die technischen Probleme bei Vermengungen von Bedeutungen kommen.

Was meint die Fachabteilung eigentlich, wenn Sie von Kunden spricht?

Quelle: Fotolia

Jede Fachabteilung spricht von dem sogenannten Kunden (Quelle: Fotolia)

Heute war ein Meeting mit dem Rechnungswesen. Sie wollen eine Änderung, um einfacher die Kontodaten unserer Kunden ändern zu können. Letzte Woche sollte unser Kampagnen-Tool fürs Marketing dahingehend erweitert werden, dass sich detaillierter Informationen zu den Kunden sammeln lassen. Und nächste Woche, so wurde mir gesagt, soll ich mit dem Verkauf sprechen, um in den Gutschriften für Kunden einen Passus zu ergänzen.

Ups, was ist da los? Alle Welt spricht von dem ‚Kunde‘. Aber ist dabei immer der gleiche Kunde gemeint? Also natürlich ist es dieselbe Firma bzw. Person, aber ist auch das gleiche Konzept gemeint? Oder anders gefragt: Würde das Rechnungswesen Informationen über die Kundenbeziehungen ändern oder würde der Versand Änderungen an Gutschriften durchführen? Wohl eher nicht. Benötigt denn der Kundenservice in seiner Oberfläche Informationen wie die Bankverbindung oder muss das Rechnungswesen die abonnierten Mailinglisten des Kunden sehen können? Ups, da war es wieder: Der Kunde.

Mit diesem Artikel soll der Einstieg in eine kleine Serie gemacht werden, in der ich erkläre, warum sich viele Probleme mit der Anwendung bereits dadurch vermeiden lassen, dass die Fachabteilung bei Domänenbegriffen respektive -konzepten genauer abgrenzt und explizit macht, was sie meint.

Beispielsweise wirkt sich das, auch wenn es der Anwender nicht glauben mag, stark auf die Geschwindigkeit und die Skalierbarkeit des Programms aus. Gleichfalls ist die Erweiterbarkeit und die Entwicklungsgeschwindigkeit davon betroffen. Oder die Usability. Genauso die Sicherheit und die Fehleranfälligkeit. Ganz schön viel, was die nicht differenzierte Betrachtung eines Kunden ausmachen kann oder?

Im nächsten Teil erläutere ich Beispiele, die zeigen: Hey, das ist gar nicht so schwer eine klare Unterscheidung zu machen.

Build Server endlich ohne DevExpress

DevExpress ist leider alles andere als vorbildlich, was den Einsatz auf Build Servern angeht. Weder bietet das Unternehmen NuGet Packages, noch lässt sich die Lizenzprüfung auf dem Build Server deaktivieren.

Mit einem kleinen Trick lässt sich aber die Installation umgehen. Hierzu ruft ihr den Installer auf dem Build Server/Agent auf, loggt euch mit euren Daten an dem unten aufgeführten Screenshot ein und brecht nach erfolgreichem Login ab einfach ab.

DevExpress Login Dialog

Damit wurden mehrere Registry Einträge geschrieben, die leider maschinenspezifisch sind. Diese findet ihr hier:

  • HKLM\SOFTWARE\Classes\Licenses378852D-D597-4A32-B6D9-680A16A3CDA6\***
  • HKLM\SOFTWARE\Classes\Licenses\6F0F8269-1516-44C6-BD30-0E90BE27871C\***

Wenn ihr in den Projekten dann DLL-Referenzen aus einem Repository-Verzeichnis verwendet oder euch eigene NuGet Packages baut, benötigt ihr in Zukunft keine Installation mehr. Das gilt auch für Developer, die nicht an der UI mitentwickeln.

Wohin mit den Queries, Repositories und UnitOfWorks in meinen Anwendungsschichten

Am vergangenen .NET Open Space gab es eine Session namens „Repositories oder ORM“. Den Titel fand ich ein wenig unglücklich gewählt. Nutzt man nämlich einen OR-Mapper, so verwendet man implizit Repositories. Zumindest ist das beim Entity Framework der Fall. Dort entspricht der DbContext nämlich der UnitOfWork und die darauf implementierte generische Set-Methode liefert die Repositories zu allen Datenbank-Entitäten.

Grob gesagt sollte pro Geschäftsvorfall (aus Sicht der UI) ein DbContext erzeugt, darauf alle Änderungen und Abfragen ausgeführt und im Anschluss per Commit in einer Transaktion ausgeführt werden. Die Transaktion findet implizit statt, sodass ihr sicher sein könnte, dass entweder alles in die Datenbank geschrieben wurde oder nichts.

Nun wurde die Frage gestellt wie mit Abfragen zu Verfahren ist: Sollte man in allen Layern auf die Repositories zugreifen und dann per LINQ beliebig filtern? Ich bin der Meinung, dass man dies tunlichst unterlassen sollte. Stattdessen nutze ich in der Regel eine der zwei Möglichkeiten (welche sich beide gut zum Testen eigenen):

  • Eine dedizierte Repository-Implementierung, die intern die Abfragen kapselt. Das könnte zum Beispiel die Klasse ‚Rechnungen‘ mit der Methode ‚AlleMitDatumGrößerAls(DateTime datum)‘  sein. Idealerweise mappt das Repository ‚Rechnungen‘ dabei die Entitäten auf Business Objekte. AutoMapper kann in dem Fall viel Schreibarbeit abnehmen.
  • Sollten mehrere Repositories die gleiche Abfrage verwenden, so bietet es sich an die Query in eine eigene Klasse dafür zu extrahieren. Zum Beispiel die Klasse ‚FindeBenutzerMitId‘, welche im Konstruktor die Id übergeben bekommt. Auf der UnitOfWork lässt sich dann die Query z.B. in der Form ausführen: ‚uow.ExecuteQuery(new FindeBenutzerMitId(1))‘. Dafür muss allerdings erst die UnitOfWork um einen solchen Mechanismus erweitert werden. Ich hatte diesen Ansatz vor ein paar Jahren in diesem Video beschrieben.

Leider ist ein Blog Beitrag ungeeignet um ein solch komplexes Thema in der notwendigen Tiefe zu besprechen. Ziel war es daher nur Denkanstöße zu geben und eine Diskussion zu starten. Wer nützliche Ressourcen zu dem Thema hat oder wer andere Ansätze verfolgt, kann diese gerne in die Kommentare schreiben.

Paket vs. NuGet

Am vergangenen .NET Open Space haben einige Teilnehmer nach Erfahrungen zu Paket, der mehr oder weniger neuen Alternative zu NuGet. Mein Statement möchte ich an dieser Stelle für alle festhalten:

Wir haben unser ERP-System mit ca. 70 Projekten vor über 6 Monaten umgestellt und sind sehr zufrieden damit. Warnen muss ich lediglich vor 3 Punkten, die einem bewusst sein müssen:

  • Paket ist nicht in Visual Studio integriert und muss daher über die Kommandozeile ausgeführt werden. Eine Integration ist auch nicht geplant. (Aktualisiert: Ein entsprechendes GitHub Projekt steht zur Verfügung)
  • Jedes NuGet Package, welches die install.ps1 aufruft, funktioniert ggf. nicht richtig nach der Installation mit Paket. Das ist z.B. bei PostSharp der Fall, was ich hier beschrieben habe. Der geneigte Leser möge bitte bei PostSharp für das offene Issue dazu voten.
  • NET Core Projekte erlauben keine Assembly Referenzen mehr, sodass Paket nicht verwendet werden kann.

Die Gründe für einen Abgang von NuGet sind vielfältig und wurden vom Entwicklerteam selbst beschrieben. Mit annähernd allen Problemen räumt Paket auf. Um nur zwei davon zu nennen:

  • Mit dem Updaten von packages werden die Projektdateien nicht mehr verändert. Stattdessen werden lediglich 2 Dateien von Paket selbst aktualisiert. Damit gehören Merge-Konflikte der Vergangenheit an.
  • Einen Abhängigkeitsgraphen bekommt man ebenfalls mitgeliefert. Daraus lässt sich schnell schließen welches Package ein anderes in welcher Version referenziert.

Eine Frage beim Open Space war, ob sich damit auch das gleiche Package in unterschiedlichen Versionen einbinden lässt. Nein, das ist nicht der Fall, was aber nichts mit NuGet oder Paket zu tun hat. Das ist der Tatsache geschuldet, dass ein .NET Prozess eine Assembly nur in genau einer Version laden kann. Zum Lösen dieses Problems bedarf es also immer Binding Redirects. In NuGet 3 soll zumindest ein Feature zum einfachen Konsolidieren unterschiedlicher Versionen eingebaut sein.

Mit NuGet 3 soll ohnehin ein großes Redesign stattfinden, sodass ein näherer Blick darauf ratsam ist. Im Team Blog finden sich einige nützliche Ressourcen.

Ich wollte den Blog Post kurz halten, deshalb habe ich nicht alle Vorteile aufgezählt. Wenn aber ein Leser der Meinung ist, dass noch etwas unbedingt genannt werden soll, dann einfach in die Kommentare posten.

Ist guter Programmcode noch wirtschaftlich

Eine Session am vergangenen .NET Open Space behandelte das Thema Wirtschaftlichkeit. Konkret stellte der Session Hoster an die Teilnehmer die Frage:

Ist es für euch wichtiger die Implementierung technisch möglichst elegant zu machen oder steht die Wirtschaftlichkeit an erster Stelle?

Ich sehe darin 3 mögliche Antworten:

  • Gerade durch die technische Eleganz steigt die Wirtschaftlichkeit, z.B. weil das Produkt bessere Performance als Konkurrenzprodukte hat.
  • Beides steht im Einklang. Würde für die Implementierung nicht die notwendige Sorgfalt aufgewendet werden, müsste das Produkt früher oder später recycelt und gänzlich neu entwickelt werden.
  • Die Wirtschaftlichkeit in Form von Manntagen zum Zwecke einer „besseren“ Umsetzung wird vermindert.

Speziell zu letztem Punkt habe ich eine ganz eigene Einstellung, zu welchem ich gerne eure Meinung hören würde. Meines Erachtens gilt es nämlich zuerst ganz andere Stellen im Produktenwicklungsprozess zu optimieren. Hierzu einige Beispiele aus meiner Praxiserfahrung:

  • Es werden Anforderungen aufgenommen, welche keinen Nutzen bringen. Diesen kommt man recht einfach auf die Schliche, indem man dem Verantwortlichen 5x die Frage ‚Warum‘ stellt. Ich schätze, dass zw. 5-10% der Anforderungen, die von den Fachabteilungen eingebracht und umgesetzt werden, keinen praktischen Nutzen erfüllen.
  • Die Priorisierung von Feature-Wünschen ist nicht gemäß deren Business Values. Wenn nicht die Dinge zuerst implementiert werden, die den höchsten Nutzen bringen und dabei das niedrigste Risiko und den geringsten Aufwand aufweisen, dann leidet die Wirtschaftlichkeit (Ausnahme: Bei einem neuen Produkte sollten die mit dem höchsten Risiko zuerst umgesetzt werden).
  • Es werden mehr neue Anforderungen aufgenommen, als umgesetzt werden können. Wenn in einem Jahr 200 Einträge im Issue Tracking System aufschlagen, aber nur 100 umgesetzt werden können, dann wurde definitiv Geld in Form von Arbeitszeit verbraten.
  • Es wird nicht die notwendige Sorgfalt in die Ausarbeitung von Anforderungen gesteckt. In einem Pluralsight Video bin ich kürzlich auf die Aussage gestoßen, dass 50-70% der Entwicklungskosten auf schlechte/falsche Anforderungen zurückzuführen sind.
  • Bei manchen Anforderungen kann erheblich viel Entwicklungszeit eingespart werden, wenn bestimmte Aspekte, auf die auch der Anwender verzichten kann, weggelassen werden. Hierbei sind die Entwickler gefragt, nachzuhaken, ob sich das Feature eventuell an der ein oder anderen Stelle reduzieren lässt.
  • Kommunikation: Der Wert einer guten Kommunikation lässt nicht beziffern.
  • Automatisierte Prozesse für sich wiederholende Aufgaben, z.B. Continuous Deployment. Das spart täglich Geld!

Das sind nur ein paar Punkte, bei denen ich als erstes Hand anlegen würde! Wie seht ihr das?

Anmeldung zum NET Open Space Süd 2015

Ich möchte auf diesem Weg Werbung für eine Veranstaltung machen, die ich sehr schätze und an der ich seit mehreren Jahren teilnehme: Der .NET Open Space Süd.

Der #NOSSUED 2015 findet vom Samstag, 18. Juli 2015, 09:00 Uhr – Sonntag, 19. Juli 2015, 16:00 Uhr in Karlsruhe statt. Zur Anmeldung geht es hier.

Meine Berichte und Live Interviews findet ihr unter dem Tag Open Space. Einen Artikel zum Open Space Format hat die dotnetpro freundlicherweise freigegeben.

NET Open Space Süd in Karlsruhe

NET Open Space Süd in Karlsruhe

Product Owner optimiert eure Engpässe

Das ist Teil 2 meiner Serie: 3 einfache Tricks für Product Owner mit großer Wirkung.

flask-304943_1280Wenn wir Software entwickeln, dann erstellen wir – wenn auch virtuell – ein Produkt. Produktentwicklung respektive der dafür eingesetzte Prozess wird immer einen oder mehrere Engpässe haben. Besonders Lean Management bzw. das darauf basierende Kanban zielen auf die Optimierung solcher Durchsatzprobleme ab (vgl. Theory of Constraints).

An allen Softwareprodukten, an denen ich mitentwickelt habe, war ein Engpass im Bereich der Entwicklung. Ideen und Wünsche haben die Kunden, Projektmanager und Product Owner viele. Natürlich können sie diese schneller formulieren als die Entwickler sie implementieren können.

Deshalb ist es wichtig genau diesen Abschnitt des Entwicklungsprozesses optimal auszulasten. Alternativ könnte der Engpass durch massive Aufstockung der Mitarbeiter vollständig aufgelöst werden, aber das ist allein aus Kostengründen unrealistisch.

 

Vorbereitung ist alles

Deshalb gilt: Je besser die Vorarbeitet ist, d.h. Wunsch-Features durchdacht, formuliert und präpariert werden, desto weniger Zeit muss der Entwickler dafür aufwenden. Unternehmen sprechen typischerweise auch vom Anforderungsmanagement. In einem späteren Beitrag werde ich die Einzelschritte und die Rollen in einem Softwareentwicklungsprozess beleuchten. Es gilt das Gleiche wie beim Essen: Je besser die Nahrung im Mund vorgekaut wird, desto einfach kann der Magen sie verdauen. Das heißt nicht, dass nicht weiter der Entwickler einbezogen werden soll oder dass weniger miteinander geredet werden soll, aber meiner Erfahrung nach werden immer wieder wenig durchdachte Anwendungsszenarien den Entwicklern über den Zaun geworfen. Im Sinne von “die werden dann schon mal machen”. Wird dann seitens der Entwickler nachgefragt, wundert sich der fachliche Verantwortliche gerne mal “was denn daran nicht klar sei”. In dem Zuge sei auf die Wichtigkeit einer gemeinsamen Sprache hingewiesen. Wie gesagt ist die Kommunikation wichtig und die Fachexperten können nicht an alles denken. Manches wissen sie auch nicht. Viele Probleme können aber im Vorfeld durchaus vermieden werden. Statt nach Lösungen zu suchen, kann es oft sinnvoller sein die tatsächliche Ursache des Problems zu untersuchen. Wo genau funktioniert der Geschäftsprozess nicht?

 

Evolvierbarkeit

Darüber hinaus muss jedem Produktverantwortlichen klar sein, dass eine Änderung nachweislich teurer wird, je später selbige erfolgt. Das betrifft die sogenannte Evolvierbarkeit. Obwohl Software nicht wie ein Auto verschleißt oder für Änderungen physikalisch auseinander gebaut werden muss, kosten späte Korrekturen mehr als frühe.

 

Schnelles Feedback

Bei Scrum und Kanban macht es sich ebenfalls bemerkbar, wie schnell erledigte User Stories vom Product Owner abgenommen werden. Ich habe für die Projekte, in denen ich Scrum Master bin, mit dem PO vereinbart, dass spätestens am Vormittag des Folgetages das Feedback kommen muss, ob die User Story korrekt umgesetzt wurde. Mir ist unter anderem von Microsoft bekannt, die nach einer Einführung einer 4-Stunden-Abnahmefrist der Durchsatz der tatsächlich abgeschlossenen Aufgaben signifikant gesteigert wurde.

 

Leerlauf vermeiden

Zu guter Letzt gibt es noch den Fall, dass die Arbeit so gut läuft, dass neue Wünsche schneller umgesetzt werden können als erwartet. Dann sollten die nächsten ToDos vorbereitet sein, damit die Software Ingenieure nicht Leerlauf haben.

 

Fazit

Der Entwicklungsprozess sollte auf die Engpässe zugeschnitten sein. Häufig ist das die Entwicklung. Diesem Engpass muss sich der Rest des Prozesses unterordnen. Das Prinzip ist seit langem bekannt, wissenschaftlich belegt und kann eine erhebliche Beschleunigung der Produktentwicklung bewirken.

Product Owner lasst eure Entwickler den Tunnel

Das ist Teil 1 meiner Serie: 3 einfache Tricks für Product Owner mit großer Wirkung.

 

Ideal zeigt der Firm ‘The Social Network’ welche Umgebung Entwickler benötigen: Den sogenannten “Tunnel”.

 

Gemeint ist damit die Möglichkeit konzentriert ohne Unterbrechung an dem (Software-)Produkt arbeiten zu können. Wenngleich agile Methoden wie Scrum und Kanban sehr stark Interaktion und Kommunikation (vgl. Agiles Manifest) fördern, fällt mir immer wieder auf, dass zwar nicht insgesamt zu viel, dafür aber zu häufig miteinander gesprochen wird. Statt dedizierte Gesprächstermine zu nutzen, ruft der Product Owner teilweise mehrfach am Tag den Entwicklern an, um sich z.B. Feedback zu Ideen oder neuen User Stories zu holen.

Das wirkt dann natürlich sehr flexibel im Sinne von frei von Bürokratie und klingt auf Anhieb sehr “kommunikativ”, jedoch sehe ich auch die Nachteile, die nach meiner Ansicht stark überwiegen: Der Entwickler wird kontinuierlich aus dem Tunnel gerissen. Gerade in kleinen und mittelständischen Unternehmen (KMUs) ist die Begründung die, dass genau die statischen Reglements von Konzernen vermieden werden wollen oder aber dass ohnehin nur wenige Entwickler zur Verfügung stehen, um den PO gedanklich zu unterstützen. Das sind alles nachvollziehbare Gründe, jedoch spricht aus meiner Sicht nichts dagegen zu sagen: Wir reservieren täglich von 16.30-17 Uhr dediziert Zeit für den Product Owner und seine Fragen weg. In Scrum gibt es sogar ein dediziertes Meeting während der Iteration dafür: Das Backlog Grooming. Dieses kann im Übrigen auch mehrfach während eines Sprints angesetzt werden.

Wie viel Zeit kleine Ablenkungen kosten, belegen neben Studien (von denen ich an dieser Stelle keine heraussuchen will) auch die eigenen Erfahrungen. E-Mail Eingang, Messenger Nachricht oder nur schnell im Internet was nachgeschaut und schon ist man aus dem Fokus und dem Gedankengang draußen. Das ist unabhängig vom Entwicklerberuf, das ist einfach menschlich. Je nachdem welche Studie gerade wieder veröffentlicht wird, lese ich Zeitangaben zw. 10 und 30 Minuten, die benötigt werden, um wieder an der gleichen Stelle mit der gleichen Konzentration weiterzuarbeiten.

Der geneigte Product Owner kann das einfach nachvollziehen, indem er sich an seine Schulzeit erinnert. Wenn er als Schüler eine mathematische Aufgabe rechnen muss, deren Lösung durch verschiedene Rechenschritte und Umformungen sich auf über 2 DIN A4 Seiten erstreckt und er Mitten drin von einem Mitschüler 5 Minuten mit einem völlig anderen Thema abgelenkt wird, dann muss er nach dem Gespräch erst nochmal seinen Gedankengang verfolgen, um die Rechnung weiterführen zu können.

WhatsApp auf Android automatisch in die Cloud sichern

Ist dir das auch schon passiert,

  • dass dein Handy geklaut wurde oder kaputt ging und deine ganzen WhatsApp Nachrichten, Bilder und Videos weg waren?
  • dass dein Handyspeicher ständig voll ist, weil die Multimedia-Daten von WhatsApp einfach zu groß sind?
  • dass du auf ein neues Handy gerne deine gesamte WhatsApp Kommunikation übertragen hättest

Wenngleich es sehr viele Lösungen im Netz gibt, sind nur wenige davon für den weniger geübten Anwender geeignet. Die Firma MetaCtrl bietet für Android entsprechende Apps an, womit sich Verzeichnisse auf dem Smartphone automatisiert in den eigenen Cloudspeicher synchronisieren lassen. Nutzt du also Dropbox, OneDrive, Google Drive oder Box ohnehin schon, so ist das eine einfache Lösung. Exemplarisch möchte ich das für Dropbox zeigen:

Die zugehörige App heißt Dropsync (für andere Cloud Dienste findest du die zugehörigen Apps hier). Die App einfach installieren und starten. Dann musst du der App Zugriff auf Dropbox gewähren. Dazu einfach das vorausgewählte Dropbox Konto anklicken und zulassen.

2015-04-18 12.09.38

Als nächstes kannst du dann ein Verzeichnis zur Synchronisation auswählen. Angefangen beim lokalen Verzeichnis, was logischerweise ‘WhatsApp’ heißt. Danach musst du das Verzeichnis in der Dropbox auswählen, wohin die Daten gespeichert werden sollen. Am besten kurz ein neues Verzeichnis anlegen, das du auch WhatsApp nennen kannst. Nun muss nur noch die Synchronisationsmethode ausgewählt würden. Ich würde “nur Uploads” vorschlagen. Was das genau bedeutet, könnt ihr in der App nachlesen.

2015-04-18 12.10.16

Der Vorteil ist, dass damit jederzeit lokal Bilder und Videos gelöscht werden können, diese aber weiterhin in der Cloud bleiben. Außerdem ist im lokalen WhatsApp Verzeichnis auch die benötige Datei, welche für eine Wiederherstellung auf einem anderen Handy benötigt wird.

Das Wiederherstellen ist im Übrigens sehr einfach. Auf dem neuen Handy ebenfalls die App installieren, das WhatsApp Verzeichnis in der Dropbox als Quelle auswählen und lokal ein WhatsApp Verzeichnis erstellen. Als Methode wählst du dann “nur Downloads”. Nachdem das Verzeichnis vollständig synchronisiert wurde, kannst du WhatsApp auf dem Smartphone installieren. Beim ersten Starten wird dein Konto erkannt und eingelesen. Voila, alle Daten wieder da. Jetzt solltest du aber nicht vergessen die Synchronisationsmethode wieder auf “nur Uploads” zu stellen.

 

Am Ende habe ich noch mehrere wichtige Hinweise:

  • Denkt gut darüber nach, ob ihr eure Konversationen und Daten in einem Cloud Speicher sichern wollt. Wer allerdings schon WhatsApp nutzt, nimmt es mit dem Datenschutz ohnehin nicht genau.
  • Die kostenlose Variante von Dropsync ist beschränkt. Es können Dateien von max. 8 MB hochgeladen werden, was bedeutet, dass v.a. größere Videos nicht gesichert werden. Bilder und kleine Videos sind in der Regel davon nicht betroffen. Für 6€ gibt es die Variante ohne Einschränkungen.
  • Stellt in den Einstellungen ein, dass nur bei aktivierter W-LAN Verbindung Daten synchronisiert werden sollen.
  • Generell muss natürlich in der Dropbox genügend freier Speicher zur Verfügung stehen. Kleiner Tipp: OneDrive bietet mehr freien Speicher und ist als Sicherungsplatz für Handydaten völlig ausreichend

2015-04-18 12.09.452015-04-18 12.09.53

Incorrect password or no TrueCrypt volume found

Mein Laptop ist vollständig mit TrueCrypt verschlüsselt. Jedoch konnte die zweite Partition, welche mit genau dem gleichen Passwort verschlüsselt wurde, nicht geladen. Stattdessen erhielt ich folgende Fehlermeldung:

image

Hintergrund ist der, dass ich ein deutsches Tastaturlayout verwende. Nachdem ich mehrere Methoden, wie sie im Netz zu finden sind, vergeblich durchführte, nahm ich eine Abkürzung und stellte einfach das Passwort um. Ab jetzt nutze ich nur noch Zeichen, die sowohl auf der englischen als auch der deutschen Tastatur gleich sind. Stichwort y/z und Konsorten.

Das Ändern des Kennworts ging übrigens in wenigen Sekunden, sodass ihr nicht wie bei der initialen Encryption mehrere Stunden für den Vorgang veranschlagen müsst.

Microsoft TechCamp Week mit Hackathon in Pforzheim

Microsoft und die Medien-IT-Initiative Pforzheim veranstalten im Mai ein TechCamp in Pforzheim. Die Veranstaltungen sind kostenlos, jedoch ist für jeden Tag eine Anmeldung notwendig. Hier findet ihr die direkten Links zu Anmeldung.

imageAufgrund meiner Erfahrung (1,2,3) kann ich speziell den Hackathon in Pforzheim empfehlen. Der ist jedes Mal eine tolle Sache. Danke an Petra von der Medialesson GmbH, die mich darauf aufmerksam gemacht hat.

%d Bloggern gefällt das: