Be pragmatic, this is a guide.
Engage with Customer / Domain experts
Encourage them to describe their process and root problem.
Create a dialog.
Record linguistics in the Domain Directory.
Aim to determine Value and Risks.
Estimate based on “Done Done”.
Also see: Value Streams
Environment which makes development more predictable, with less risk, more value and less cost.
Enables responding to change and continues adding of value.
Working (meets requirements), well crafted (is maintainable) software
Customer collaboration and tight feedback loop.
Share knowledge.
Be honest.
Retrospectives allow continued improvements.
Less is more, say no, reduce scope.
Own feature from specification to delivery to production. [pipeline]
Pull requests for none-trivial changes, require at least one other developer to give a thumbs up.
High-level customers discussions and specifiction happens in Redmine.
The Redmine spec is split in to multiple Pivotal Tracker stories
Pivotal Tracker stories are estimated, any difficult to estimate stories either need exploration or reducing in scope.
Mark stories with Redmine number, [rm/1234].
Time should be tracked for a unit of work and include the RM, PT id's and project. [TODO]
Hexaganol / SOA
Dependencies point inwards, e.g. Database can depend on something in core domain but not visa versa.
Language within a Context. Words can have different meaning in different contexts.
Avoid workarounds.
Entity - Object with an identity (e.g. a Person).
Where possible use natural keys as the id, e.g. social security number.
Value Object - object without an identity (e.g. an Address).
Aggregate - a combination of related entities and values (e.g. an Order which contains LineItem's). One entity will be the root of the aggregate through which the other entities are fetched.
In the case of an Order, the LineItem's are never access directly, only via an Order. The Order might also have a delivery Address and a DeliveryStatus.
Use service objects (e.g. PlaceOrder), to perform actions for anything other than simple CRUD. We should use the language of the domain, instead of CreateOrder, if the domain expect says "place order" we should use PlaceOrder.
Always separate core domain logic from external resources (e.g. database, HTTP services, cache, file system) - see: hexagonal architecture. Do this by creating an interface (port) which has a plugable backend (adapter).
Separate UI concerns from the core domain by wrapping domain objects in presenters.
Prefer emitting an event over callbacks/observers.
When testing something which does not process requests, do not require all of Rails.
Refactor specs for readability
unit tests - test a single unit in isolation. Anything external is mocked.
integration tests - test collaberation between one or more objects, anything outside the core domain is stubbed, or an in-memory version used.
end-to-end tests - test an entire slice of the system, nothing mocked.
acceptance tests - test the UI from the business perspective
Methods should either be command or query methods.
Command methods must always return self
Constructors are except from the above rule (e.g. initialize method and factory classes).
Query method can return any value and must not have any side effects (e.g. state changes)
Query methods should not return nil, instead return a “null object”.
Use Ruby hashes where possible
Use Keyword arguments instead of options hash