This is a viewer only at the moment see the article on how this works.
To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk
This is a preview from the server running through my markdig pipeline
Spielen mit einem effizienten agilen Ansatz
Sunday, 23 November 2025
Warum Ihren Zweig wie eine Sandbox behandeln und als legitime Arbeit spielen?—Erzeugt bessere Software mit weniger Stress.
Heiße Einnahme Die meisten Entwickler versuchen, in jeder Phase der Entwicklung perfekt zu sein und es 'es tötet sowohl ihre Kreativität als auch ihre Produktivität.
Einleitung
I'®ve wurde Bau-Software professionell für...... well...,] let.''s nur sagen, dass ich mich erinnere, als... "„Agile" eine neue Idee war und nicht ein Unternehmensbuzzword, das von Projektmanagern bewaffnet wurde, um mehr Standups zu rechtfertigen.
Im Laufe der Jahre wurde mir etwas aufgefallen. Der beste Code, den ich jemals geschrieben habe, kam von Projekten, in denen ich fühlte Berechtigung zum SpielenDer schlimmste Code kam von Projekten, bei denen jeder Tastendruck sich anfühlte, als ob er untersucht würde.
Dies ist nicht zufällig. Kreativität und Druck vermischen sich gut
So hat I'-ve einen Ansatz entwickelt, der die chaotische kreative Exploration von der polierten ,-Produktion trennt.-...ready delivery... ich nenne es "Machen Sie es work-, , machen Sie es hübsch - , , verriegeln Sie es nach unten-, aber wirklich ,, es über geben sich selbst die Erlaubnis zu experimentieren, ohne das Gewicht der Perfektion hängend über Ihnen .
Die drei Phasen
Lassen Sie mich klar sein Upfront-:, dies ist .' . . über Sein schlampig oder Vermeiden von Disziplin . zur richtigen Zeit die richtige Disziplin anwenden.
graph LR
subgraph "Phase 1: Make It Work"
A[New Requirement] --> B[Explore & Experiment]
B --> C{Does It Work?}
C -->|No| D[Try Different Approach]
D --> B
C -->|Yes| E[Basic Solution]
end
subgraph "Phase 2: Make It Pretty"
E --> F[Refactor & Clean]
F --> G[Apply SOLID Pragmatically]
G --> H[Get Stakeholder Feedback]
H --> I[Polished Solution]
end
subgraph "Phase 3: Lock It Down"
I --> J[Add Tests]
J --> K[Security Review]
K --> L[Add Monitoring]
L --> M[Production Ready]
end
style A stroke:#f59e0b,stroke-width:3px
style E stroke:#0ea5e9,stroke-width:3px
style I stroke:#8b5cf6,stroke-width:3px
style M stroke:#10b981,stroke-width:4px
Phase - 1:- machen Sie es funktioniert
Das Mantra-: Spielen Sie zuerst..-Bestätigen Sie Ihre Annahmen.
Dies ist die Phase, in der dein Zweig eine Sandbox ist. in OrdnungSie bauen hier nicht eine Kathedrale, sondern zeichnen auf einer Serviette
Was Sie versuchen, um herauszufinden, :
- Benimmt sich diese API tatsächlich, wie die Docs behaupten, dass es selten )
- Kann ich dieses Problem sogar mit den Werkzeugen lösen, die ich habe?
- Was sind die tatsächlichen Anforderungen nicht diejenigen, die im Ticket geschrieben werden?
- Ist dies ein zwei---Stunden-Problem oder ein zwei ---Wochen-Problem?
Die kritische Einsicht Bis du einen PR-,h erhöhst, ist dein Zweig DeinesEs ist immer noch frei, dass die POINT-. - auch als drei---Cade-Veteranen , - nicht zu sehen, was Ihre falschen Starts sind., - Ihr kommentierter Debugging-Code , - Ihr experimentelles Labor Niemand muss Ihre falsche Starts sehen.MSC3 - Ihre kommentierten - - nicht debugging code...MSK5 - das ist schrecklich , - fix later?" - aber überprüfen Sie in OFTEN - — - jedes Mal wenn Sie etwas haben, das funktioniert, , - begehen und drücken Sie . - Haken Sie in Ihre CI-Pipeline ... eine gute Pipeline wird Ihnen mehr Informationen geben.
Nebennutzen Häufige Verabredungen sind ein Herzschlag... In Remote-/.async-Teams... eine stetige Spur von ".ugly, aber fortschreitend.".commits beruhigt jeden, dass die Arbeit sich bewegt, ohne dass du Produktivität in Slack.MSC6 durchführen musst.
Diese psychologische Freiheit ist essenziell Wenn du weißt, dass du alles wegwerfen kannst und neu anfängst – , – machst du kühnere Entscheidungen. – Du versuchst diesen seltsamen Ansatz, der wahrscheinlich gewonnen hat –' – keine Arbeit. – Manchmal funktioniert es brillant – . – manchmal musst du einen Artikel lesen – , – ein YouTube-Video anschauen – , – denken Sie für eine Weile daran – : – Ihre Aufgabe besteht darin, gute Software und gute Entscheidungen zu liefern – , – nicht schnell einzutippen – MSC11 – Gute Manager verstehen dich – MSSK12 – mehr NICHT EIN TYPIST.
// Phase 1 code looks like this - and THAT'S OKAY
public async Task<Result> ProcessThing(Request req)
{
// TODO: what if this is null?
var data = await _api.GetSomething(req.Id);
// This probably isn't right but let's see what happens
var transformed = data.Items
.Where(x => x.Status != "deleted") // Is this the right filter?
.Select(x => new Thing { Name = x.Name }); // Missing loads of fields
// HACK: hardcoded for now
return new Result { Items = transformed.ToList(), Total = 42 };
}
Ist dieser Produktionscode???Gott nein .?Ist es nützlich??? Absolut!.?Es sagt Ihnen, ob Ihr Ansatz sogar lebensfähig ist, bevor Sie Stunden polieren etwas investieren, das nicht funktioniert..?
Ein Hinweis auf das Feedback Sie können Feedback erhalten unter keine Punkt in Phase 1— der Schlüssel ist die Wahl Wer Das Ziel ist es, das beste Feature zu bauen.,... nicht einem starren Prozess zu folgen.
Eine API zu bauen, die ein anderes Team konsumieren wird, kann Tage der Nachbearbeitung retten... Etwas für einen Benutzer aufbauen...?.Vielleicht halten Sie sich davon ab, den Stakeholder zu zeigen, bis er weniger grobe —.Einige Leute aufhängen, wie etwas sieht aus eher als ob es ArbeitenDass ''s fein ist, dass sie Feedback in Phase geben
Verwenden Sie Ihr Urteil .. . Manchmal brauchen Sie Feedback zu klarstellenDas Spezifik sagt, dass ' Handle Fehler anmutig '— ist, die drei Mal wiederholen , oder schnell scheitern und benachrichtigen, dass' ein Phase-1-Gespräch
Wenn eine Stakeholder-Input ist kritisch, aber they-'.D Kampf mit groben Code ?,? bauen Sie ein triviales Demo ?.? Ein hartkodierter Happy---Pfad, der zeigt, dass das Konzept kann wertvolles Feedback freischalten ohne die Ablenkung von fehlenden Randfälle ? .?
Das Ziel ist die beste Funktion, nicht Prozessreinheit, sondern
Phase machen Sie es schön
Das Mantra-: Jetzt, da du weißt, was du erbaust, mache es gut.
Die explorative Phase hat seine Arbeit getan ,. , Sie haben bestätigt, dass der Ansatz arbeitet , , , verstehen Sie die Form des Problems , und you , ' , entdeckt wahrscheinlich ein Dutzend Randfälle das ursprüngliche Ticket didn .' , nicht erwähnt
Jetzt säuberst du es auf.
// Phase 2: Same logic, but actually maintainable
public async Task<ProcessingResult> ProcessItemsAsync(
ProcessingRequest request,
CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(request);
var items = await _itemRepository.GetActiveItemsAsync(
request.AccountId,
cancellationToken);
var processedItems = items
.Where(item => item.Status != ItemStatus.Deleted)
.Select(item => _mapper.ToProcessedItem(item))
.ToList();
return new ProcessingResult
{
Items = processedItems,
TotalCount = processedItems.Count,
ProcessedAt = _timeProvider.UtcNow
};
}
Hier bist du.
- SOLID-Grundsätze anwenden pragmatisch Sie kennen sie, aber verehren sie nicht.
- Geben Sie den Dingen richtige Namen
- Typ-Hinweise und XML-Dokumentation hinzufügen
- Denken Sie an die API-Oberfläche aus der Perspektive des Callers.
- Handle die Kantenfälle, die du in Phase entdeckt hast
Kritischerweise ist dies der beste Zeitpunkt für nicht--. Technische Stakeholder Feedback Die Funktion ist jetzt sichtbar und verwendbar ,, , aber Sie haben noch nicht Stunden schriftlich Tests für sie , . , Wenn sie sagen , ," , eigentlich , , , wir wollten es zu tun X statt , ," , können Sie pivot ohne die Herzpause des Löschens einer umfassenden Test-Suite ,
Phase Verriegeln Sie es
Das Mantra-: Härten Sie es ,, , testen Sie sie , , , machen es belastbar , . ,
Jetzt— und nur jetzt—.Sie schreiben Ihre Tests..Hinzufügen Sicherheitskontrollen..Implementieren Sie die richtige Fehlerbehandlung für Produktionskantenfälle..Fügen Sie Überwachung und Leitplanken hinzu
Warum bis jetzt warten? Sie wissen endlich, was du testest.
Tests, die in Phase geschrieben wurden, wären falsch gewesen. korrektDie Implementierung ist stabil.
[Theory]
[InlineData(0)]
[InlineData(1)]
[InlineData(100)]
public async Task ProcessItemsAsync_WithValidRequest_ReturnsCorrectCount(
int itemCount)
{
// Arrange
var items = _fixture.CreateMany<Item>(itemCount).ToList();
_mockRepository
.Setup(r => r.GetActiveItemsAsync(It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(items);
// Act
var result = await _sut.ProcessItemsAsync(
new ProcessingRequest { AccountId = Guid.NewGuid() });
// Assert
result.TotalCount.Should().Be(itemCount);
result.Items.Should().HaveCount(itemCount);
}
[Fact]
public async Task ProcessItemsAsync_WithNullRequest_ThrowsArgumentNullException()
{
// Act & Assert
await _sut.Invoking(s => s.ProcessItemsAsync(null!))
.Should().ThrowAsync<ArgumentNullException>();
}
[Fact]
public async Task ProcessItemsAsync_ExcludesDeletedItems()
{
// Arrange
var items = new[]
{
new Item { Status = ItemStatus.Active },
new Item { Status = ItemStatus.Deleted },
new Item { Status = ItemStatus.Active }
};
_mockRepository
.Setup(r => r.GetActiveItemsAsync(It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(items);
// Act
var result = await _sut.ProcessItemsAsync(
new ProcessingRequest { AccountId = Guid.NewGuid() });
// Assert
result.Items.Should().HaveCount(2);
}
Diese Phase schließt auch ein:
- Sicherheitsüberprüfung (-Authentifizierung ,-Zulassung ,-Eingangsvalidierung )-Authentifizierung
- Concurrency Erwägungen, was unter Last geschieht
- Failure-Modus Analyse Was ist, wenn die Datenbank langsam ist?
- Überwachung (-how werden wir wissen, wenn diese Unterbrechungen in der Produktion
Feedback Choreographie
Verschiedene Menschen sollten in verschiedenen Stadien beteiligt werden . .. , Versteh das falsch und du ertrinkst in Reibung .
graph TB
subgraph "Phase 1: Technical Voices"
P1[Make It Work] --> T1[Senior Dev Review]
T1 --> T2["Does the approach<br/>make sense?"]
T2 --> T3["Any obvious<br/>architectural issues?"]
end
subgraph "Phase 2: Non-Technical Voices"
P2[Make It Pretty] --> N1[Product Owner Demo]
N1 --> N2["Does it meet<br/>the requirement?"]
N2 --> N3["Is the UX<br/>intuitive?"]
end
subgraph "Phase 3: Ops/Security Voices"
P3[Lock It Down] --> O1[Security Review]
O1 --> O2[Operations Review]
O2 --> O3["Will it hold up<br/>in production?"]
end
T3 --> P2
N3 --> P3
style T1 stroke:#3b82f6,stroke-width:2px
style N1 stroke:#8b5cf6,stroke-width:2px
style O1 stroke:#ef4444,stroke-width:2px
Phase Nur technische Stimmen - — senior devs , , architects ,. , Sie können das Chaos an der Form der Lösung vorbei sehen Nicht-- Technische Stakeholder werden bei grobem Code in Panik geraten und nach Knopffarben fragen, wenn du noch das Datenmodell erfährst.. ,
Phase Nicht---technische Stimmen willkommen Die Funktion ist nutzbar ,-Tasten tun Dinge erhalten .-Produktbesitzer und Designer beteiligt jetzt —-Änderungen sind immer noch billig ,-Sie haben nicht geschriebene Tests noch .
Phase Ops und Sicherheitsstimmen." Was, wenn dies bekommt 10-x Verkehr?"M"Was, wenn jemand übergibt bösartige Eingaben Diese Bedenken sind nur dann wichtig, wenn das Feature tatsächlich funktioniert.
Zweige als Sandkästen
Hier ist die Sache, die mein Entwicklungsleben verändert hat. bis du einen PR-,h erhöhst, ist dein Zweig völlig privat.
Das mag offensichtlich klingen, aber ich sehe Entwickler jeden Commit wie es behandeln.'s gehen auf ihre permanente Platte.MSC3re Angst davor zu experimentieren, .e Angst, hässlichen Code zu schreiben.
Ich möchte, dass du deinen Feature-Zweig als Sandkasten betrachtest... ein Spielplatz... ein Labor, in dem Explosionen erwartet werden und niemand verletzt wird.
graph TD
A[Feature Branch Created] --> B[Experiment Freely]
B --> C{Did it work?}
C -->|No| D[Try Something Else]
D --> B
C -->|Yes| E[Clean Up the Mess]
E --> F[Interactive Rebase]
F --> G[Squash to Clean Commits]
G --> H[Raise PR]
H --> I[Public Code Review]
style B stroke:#f59e0b,stroke-width:3px
style D stroke:#f59e0b,stroke-width:2px
style H stroke:#10b981,stroke-width:3px
subgraph "Private - Go Mental"
B
C
D
E
end
subgraph "Public - Be Professional"
H
I
end
In der Praxis bedeutet dies:
- Häufig kompilieren, auch wenn der Code nicht kompiliert
- Schreiben
FIXMEundTODOKommentare überall - Lassen Sie Debugging-Code an Ort und Stelle, während Sie erkunden
- Haben Sie mehrere ".Try diesen Ansatz ,".commits
- Don-' keine Sorge über die Übertragung von Nachrichten
Dann, bevor du ein PR-: erhebst
- Bereinigen Sie den Code
- Tests hinzufügen
- Interaktive rebase zu zerquetschen all die unordentliche Geschichte
- Eine korrekte Commit-Nachricht schreiben
Die PR-Rezensenten sehen clean-,-professionellen Code mit einer klaren Erzählung... Sie sehen nicht die sechs falschen Starts... die ,... die "-why doesn-'.t diese blutige Arbeit... die, oder die Geschichte...
Der Sandkasten bleibt privatDie polierte Arbeit geht öffentlich
Warum das Stress reduziert
Traditionell, zu jeder Zeit professionell, zu allen Zeiten, zur Entwicklung von "... jede Linie fühlt sich permanent an... jede Entscheidung fühlt sich konsequent an. Spiel ist legitime Arbeit in der Phase Das Feedback kommt, wenn das Drehen billig ist in Phase Das Signal 1 und Tests werden einmal richtig geschrieben in Phase . Das Signal 2, weil Sie endlich wissen, was man testet
Spiel ist legitime Arbeit
TDD funktioniert brillant, wenn die Domäne gut verstanden ist oder you-' pinning ein bekannter Fehler ist.. Aber wenn das Problem immer noch fuzzy ist, bedeutet das Schreiben von Tests zuerst oft das Testen der falschen Sache drei Mal in einer Reihe, ..
Pragmatische SOLID und schmutziges Geheimnis
Also, was tut diese drei---Phasen Mindset zu Ihren Designprinzipien zu tun?Im Kurztext tötet es dogma... Hier...'.s, wie es mein Denken über SOLID.,.DRY.MS K6 und Schnittstellen in C.MSC7 verändert.
Ich erwähnte die Anwendung von SOLID-Prinzipien.
SOLID ist ein guter Satz von Prinzipien, die ich ihnen beigebracht habe... Ich verwende sie, aber IM'.Ich sah Teams verschwinden Abstraktion Kaninchenlöcher im Namen der Single Responsibility oder Open-/.Geschlossene ,.
Hier ist mein heuristisches
SOLID anwenden, wenn
- Sie haben Beweise, dass Sie die Flexibilität benötigen
- Die Abstraktion macht den Code klarer
- Sie bauen etwas, das andere benutzen werden
Nicht anwenden SOLID, wenn
- Sie spekulieren über zukünftige Anforderungen
- Die Abstraktion fügt Komplexität ohne Klarheit hinzu
- Sie bauen internen Code, den nur Sie pflegen
Drei ähnliche Zeilen des Codes sind besser als eine vorzeitige Abstraktion. Sie können immer extrahieren später, wenn Sie das Muster klar sehen.
// Over-engineered SOLID worship
public interface IThingProcessor { }
public interface IThingProcessorFactory { }
public class ThingProcessorFactory : IThingProcessorFactory { }
public class ThingProcessor : IThingProcessor { }
public class ThingProcessorDecorator : IThingProcessor { }
public class ThingProcessorValidationDecorator : IThingProcessor { }
// What you probably actually need
public class ThingProcessor
{
public async Task<Result> ProcessAsync(Thing thing)
{
// Just do the thing
}
}
Wenn du die Flexibilität später benötigst, ist das Refactoring billig... Über--.Engineering vor der Tür ist teuer, weil du die Abstraktionsschichten aufrecht erhältst, die '.t verdienen ihren Halt.
Die Trockenfalle
Und während wir, ', sakrale Kühe töten, lassen wir uns von uns reden. TIERE Es ist vielleicht das dogmatischste angewandte Prinzip in unserer Branche, und wenn es ohne Gedanken angewendet wird, verursacht es mehr Schaden als gut.
Das Problem ist: nicht alle Vervielfältigung ist die gleiche Art von Vervielfältigung.
Wenn zwei Teile des Codes ähnlich aussehen, aber verschiedene Zwecke dienen... sie in eine gemeinsame Abstraktion zu extrahieren Paare Dinge, die unabhängig entwickeln sollten.... jetzt, wenn ein Anwendungsfall ändern muss....
- Hinzufügen von Parametern und Bedingungen, um beide Fälle zu behandeln.
- Durchbrechen des anderen Anwendungsfalles
- Kopieren des freigegebenen Codes wieder heraus und bearbeiten Sie es DRY zuzustimmen war hier falsch.
// "DRY" solution - looks clever, causes pain
public async Task<Result> ProcessEntity<T>(
T entity,
bool validateFirst = true,
bool sendNotification = false,
Func<T, bool>? customFilter = null,
Action<T>? preProcess = null,
Action<T>? postProcess = null) where T : IEntity
{
// 50 lines of conditional spaghetti trying to handle
// "processing" for Users, Orders, and Products
// because they all had 3 similar lines once
}
// What you probably actually need
public async Task<Result> ProcessUser(User user) { /* 15 clear lines */ }
public async Task<Result> ProcessOrder(Order order) { /* 15 clear lines */ }
public async Task<Result> ProcessProduct(Product product) { /* 15 clear lines */ }
Ja, ,, dort, ', einige ", duplizieren - ", im zweiten Ansatz, aber jede Methode ist :.
- Leicht zu verstehen in Isolation
- Einfach zu ändern ohne Nebenwirkungen
- Einfach zu löschen, wenn dieser Entity-Typ weggeht
- Einfach zu testen mit klaren Ein- und Ausgängen
Die DRY-Version ist ein Alptraum zu pflegen, weil es versucht, alle Dinge für alle Anrufer zu sein.Jede Änderung erfordert das Verständnis aller Anwendungsfälle.
Meine Regel Duplizierung tolerieren, bis du die gleich Sache dreimal und du, '- sind zuversichtlich, es repräsentiert die gleich Konzept, das sich zusammen entwickeln wird ,. , Bis dann ein bisschen Kopie , - , Paste ist fein , . , Es ist nicht ein moralisches Versagen , ; , es ist angemessen Vorsicht
Duplizieren ist viel billiger als die falsche Abstraktion.. , Sie können immer später deduplizieren, wenn das Muster klar ist.. , Du kannst ' nicht leicht eine schlechte Abstraktion rückgängig machen, die durch deine Codebase gewebt wird.
Das Interface-Problem in C.M.S.
Hier ist eine weitere heilige Kuh, die schlachten muss. benötigt die jede Klasse ein Interface, das Muster.
Zurück in den frühen Tagen von -.-NET Abhängigkeitsinjektion -, , jemand entschieden, dass Code testbar machen , , , Sie mussten Schnittstellen überall injizieren , die Logik war , : , können Sie , mock eine Betonklasse , so dass jeder Service braucht IService und ServiceImplPlötzlich wurde jede Codebase mit einzelnen ,-'-Implementierungsschnittstellen übersät, die rein zum Testen existierten.
// The interface tax - early 2010s style
public interface IUserService { }
public interface IOrderService { }
public interface IEmailService { }
public interface INotificationService { }
public interface IPaymentProcessor { }
public interface IInventoryManager { }
// Each with exactly ONE implementation
public class UserService : IUserService { }
public class OrderService : IOrderService { }
// ... you get the idea
Das war Frachtkult-Programmierung... Wir zahlten eine Kompliziertheitssteuer für Theoretische Prüfbarkeit und Theoretische Zukunftsflexibilität, die selten materialisiert wurde
Hier ist das Ding, das du nicht mehr brauchst.
Moderne spöttische Rahmen wie NErsatz und Moq kann Betonklassen mit virtuellen Methoden verspotten)..Wichtigeres: ,.ASP...NET Core...'.s DI-Container funktioniert perfekt mit Betontypen
// Modern approach - just register the concrete type
services.AddScoped<UserService>();
services.AddScoped<OrderService>();
services.AddScoped<EmailService>();
// In your controller or service
public class OrderController(OrderService orderService, UserService userService)
{
// Primary constructor injection - clean and simple
}
Keine Schnittstellen IOrderServiceGenau der Service, den Sie benötigen, wird direkt injiziert.
Aber was ist mit dem Testen? Ich höre dich weinen.
Für Einheitstests du hast Optionen
- Schlüsselmethoden schaffen
virtualund verwenden einen spöttischen Rahmen - Verwenden Sie den realen Service mit einer Testdatenbank -( Integrierungstests sind oft sowieso wertvoller
- Eine Schnittstelle hinzufügen wenn Sie es wirklich zum Testen brauchen
Dieser dritte Punkt ist entscheidend. Refactoring-Tools sind außerordentlich gut beim Extrahieren von Schnittstellen.
Im Rider oder Visuellen Studio Ctrl+. Alle Methoden werden extrahiert,, die Klasse wird aktualisiert, um es zu implementieren,, und Sie können finden./ Ersetzen Sie alle Verwendungen, wenn nötig.
// Phase 1 & 2: Just write the class
public class OrderService
{
public async Task<Order> CreateOrderAsync(CreateOrderRequest request) { ... }
public async Task<Order?> GetOrderAsync(int orderId) { ... }
public async Task CancelOrderAsync(int orderId) { ... }
}
// Phase 3: Need to mock it for testing? Extract interface in 2 seconds
public interface IOrderService
{
Task<Order> CreateOrderAsync(CreateOrderRequest request);
Task<Order?> GetOrderAsync(int orderId);
Task CancelOrderAsync(int orderId);
}
public class OrderService : IOrderService { ... }
Mein Workflow jetzt. Schnittstellen kommen in Phase -3, , nicht in Phase.
Während " machen es funktioniert " und " Machen Sie es hübsch ", Ich schreibe nur Klassen , . Aus Keine vorzeitige Abstraktion , . Aus Keine Schnittstellensteuer auf jeden Typ . Aus Der Code ist einfacher zu navigieren , Kein Springen zwischen IFoo und FooUnd schneller zu schreiben.
Wenn ich Schlagen " sperren Sie es nach unten " und müssen Tests schreiben dann Ich entscheide, welche Dienste eigentlich verspotten müssen... normalerweise ist es ' weniger als you. 'hd think.—hoften nur externe Integrationen wie HTTP-Clients, Datenbanken und Nachrichten Warteschlangen.
Für interne Business-Logik Dienstleistungen... die Hälfte der Zeit teste ich sie einfach direkt mit realen Abhängigkeiten.... die Tests sind sowieso wertvoller, weil sie das tatsächliche Verhalten testen. denken das Verhalten sollte sein
// Services I typically DO extract interfaces for (external boundaries)
public interface IPaymentGateway { } // Third-party API
public interface IEmailSender { } // External service
public interface IBlobStorage { } // Cloud storage
// Services I typically DON'T need interfaces for (internal logic)
public class OrderValidator { } // Pure logic, test directly
public class PriceCalculator { } // Pure logic, test directly
public class OrderService { } // Test with real repo + in-memory DB
Der Punkt ist: stop writing interfaces upfront -" just in case user -". schreib Betonklassen. schreib Wenn du eine Schnittstelle zum Testen oder echten Polymorphismus später benötigst, dauert das Extrahieren von , buchstäblich Sekunden mit modernen Werkzeugen.
Ihre Codebase wird einfacher sein, , Navigierbarer und Sie haben die Wartungslast von Schnittstellen im Einklang mit Implementierungen für keinen Nutzen zu halten.
Die agile Verbindung
Ironischerweise ist dieser Ansatz eher mit dem Original Agiles Manifest als die meisten -" ,Agile ," , Prozesse I' ,getroffen . ,Arbeitssoftware schnell , ( ,Phase ,1). ,Responding to change .( , Phasen , 1-2). , Kundenzusammenarbeit , wenn das Feature nachweisbar ist ,T( , Phase ,D2). ,Keine Sprintpunkte ,, , keine Geschwindigkeitsverfolgung ,mesK11 ,keine blutigen Burndown-Charts , -. ,
Modernes "-Agile" wurde von Prozessenthusiasten gefangen genommen, die so viele Zeremonien dort hinzugefügt haben.' ist keine Zeit mehr für Explorationen. Dieser Ansatz bringt das Spiel zurück...—nicht als Nachsicht... sondern als legitime Phase kreativer Arbeit...
Wenn dieser Ansatz NICHT verwendet werden soll
Ich sollte ehrlich sein... das ist immer der richtige Ansatz.
Fehlerbehebungen Wenn du einen bekannten Fehler befestigst, macht der TDD-Stil mehr Sinn.Schreibe einen Test, der den Fehler reproduziert.
Gut verstandene Probleme Wenn Sie einen Standardalgorithmus oder ein Muster implementieren, das hundertmal verwendet wurde, benötigen Sie keine Explorationsphase.
Enge Fristen mit bekannten Anforderungen Wenn Sie wirklich genau wissen, was Sie bauen und wann es zu versenden braucht, können Sie die Phase überspringen.
Hochregulierte Umgebungen Wenn jedes Commit-Zeichen benötigt wird, ist das Sandboxen härter, obwohl Sie die Exploration noch lokal durchführen können, bevor Sie . schieben.
Aber für die meisten Feature-Entwicklung, wo Anforderungen sind ein bisschen fuzzy, , ist der technische Ansatz, der offensichtliche ' ist, und Sie brauchen Raum zu denken,—, dieser Ansatz funktioniert brillant
Eine Anmerkung für Junior-Entwickler
Wenn Sie früh in Ihrer Karriere sind, könnten Sie Druck fühlen zu zeigen, dass " perfekt ist." code die ganze Zeit Sie müssen nicht . verwenden dieses drei Phasen-Ansatz verwenden.MSC8 nur klar sein, über welche Phase Sie in , sind und immer den Job bis zur Phase beenden ?3.?Niemand wird Sie für unordentliche Explorationscode beschuldigen, wenn es zu polierten , führt getestete , produktion ? - ready Code am Ende ? .
Unten
Machen Sie es work-, , machen Sie es hübsch , , verriegeln Sie es nach unten
Einfaches Design mit Voraussicht starten, aber nicht spekulieren – . Schnell iterieren –.® Nur Komplexität hinzufügen, wenn es sich auszahlt
Duplikation ist viel billiger als die falsche Abstraktion.
Die Explorationsphase ist ein schuldiges Geheimnis.—.it'.s ein definierter Teil des Prozesses...s Ihr Zweig ist Ihre Sandbox, bis Sie eine PR-..s Technisches Feedback früh zu erhöhen kommt...,.s Nicht--.stechnisches Feedback kommt mitten in der ,.s und Sicherheitsfeedback spät kommt.
Dies hält die Kreativität am Leben.,-Reduziert Stress und produziert Systeme, die elegant skalieren, weil Sie das Problem verstanden haben, bevor Sie sich der Lösung verschrieben haben.
Hören Sie auf, von Minute eins perfekt zu sein.Geben Sie sich die Erlaubnis zu spielen.
Zugehörige Lektüre
Wenn dieses resoniert, könnten Sie auch diese verwandten Posts genießen.
- Wie ich Software erstelle Weiter geht es mit detaillierten Codebeispielen der drei Phasen in die Testphilosophie hinter diesem Ansatz.
- Tägliche Standups sind Bullshit, wenn sie nicht ihre Bezahlung verdienen. Meine Annahme, warum Zeremonie steuerpflichtig ist und wie zu bewerten ist, ob Ihre agilen Rituale verdienen ihre Keep-.
- Agile Speccing®:-Writing Feature Specs, die eigentlich funktionieren Weil Spezifika Werkzeuge sind, nicht Bibeln, und sie als lebende Dokumente zu behandeln ist der einzige Weg, um das Richtige zu bauen.
- Arbeiten an Legacy-Codebases Praktische Lektionen aus Jahrzehnten des Unternehmerlebens, einschließlich wie man diese Prinzipien anwendet, wenn du ein System lernst, das du erstellt hast.