software development: beyond training wheels
TRANSCRIPT
Software Development Training wheels
Naveen Muguda
Training Wheels• Programming with Static Classes • Data Driven Design• Transaction scripts• Anemic Domain Model
Complexity vs Familiarity• lineItemList.stream().map(lineItem ->
lineItem.getTerms().getPrice()).reduce(ZERO, BigDecimal::add)• map()• reduce()• anonymous function• Is this code complex or is the programming style unfamiliar?
currying• function add (a, b) { return a + b; } • function add (a) { return function (b) { return a + b; } }• add(3)(4); • var add3 = add(3); • add3(4);
• https://en.wikipedia.org/wiki/Currying
Currying (continued)• add x y = x + y• map (add 2) [1, 2, 3] -- gives [3, 4, 5]• add2 y = add 2 y • map add2 [1, 2, 3]
Static classes• public class Position{• public double latitude; public double longitude; }
• public class PositionUtility {• public static double distance( Position position1, Position position2 )
public static double heading( Position position1, Position position2 ) }• Positions are parameters to PositionUtility
Static classes(..continued)• double distance = PositionUtility.distance( myHouse, coffeeShop );
double heading = PositionUtility.heading( myHouse, coffeeShop);
Object Oriented Programming• public class Position {• public double distance( Position position )} • public double heading( Position position ) {}• private double latitude; private double longitude; }
Object Oriented Programming(..continued)• Position myHouse = new Position( , ); • Position coffeeShop = new Position( , ); • double distance = myHouse.distance( coffeeShop );• double heading = myHouse.heading( coffeeShop );
Currying vs Object Orientedness• add(3, 4) => PositionUtil.distance(Position position1, Position
position2 ) • add 3 = > Position house = new ….• add3(4) = > house.distance(coffeeShop)• ‘identity’
Stack in procedural stylestructure stack: maxsize : integer top : integer items : array of item
procedure push(stk : stack, x : item): if stk.top = stk.maxsize: report overflow error else: stk.items[stk.top] ← x stk.top ← stk.top + 1
procedure pop(stk : stack): if stk.top = 0: report underflow error else: stk.top ← stk.top − 1 r ← stk.items[stk.top]
Stack in Object Oriented stylepublic Class Stack{ private ... public Stack(){} public push(){} public pop(){}}
Encapsulation and Information Hiding
• Changes to fields(from array to linked list), will cascade to other methods• Lazy initialization in the constructor, will move additional behavior to
push and pop
capsule• a small (glass or plastic) container that has something (such as a
liquid) inside of it.• There is an inside and outside to the capsule• There is no or partial understanding of the contents of the capsule for
the outside
Invariants• size of the stack = total valid pushs – total valid pops• stk.top is at the top of the data in the stack• The responsibility of maintaining these invariants lie with Stack• Stack is in charge of its destiny
• Single place to reason
encapsulation• encapsulate what varies• encapsulating with classes frees a dimension of change• Object oriented-ness provides currying at the object level
Spring2.0 feature• http://tinyurl.com/j7wykok
Design Approaches
Different schools• Data Driven Design: Head, Tail, Body, 4 Legs• Event Driven Design: Start, Stop, Speed Up, Slow Down• Responsibility Driven Design: eat, run, stand, sit, sleep, poop
Data driven design• Modelling done for Data(ER diagrams, DFDs)• Programs are massagers, routers and processors of data• No recommendations on modularizing the behavior• Typically this behavior is placed in classes Service, Util, Helper or
Manager.• Useful for building CRUDy applications• https://en.wikipedia.org/wiki/Data-driven_programming
Responsibility Driven Designfocuses on the contract by asking:• What actions is this object responsible for?• What information does this object share?
RDD:Objects• things that have machine like behaviors that can be plugged together
to work in concert• play well-defined roles and encapsulate scripted responses and
information• Subsystem: logical grouping of collaborators.
RDD:responsibilities• an obligation to perform a task or know information• public(checkout), private, subordinate(provider), sequencing
Data Driven vs Responsibility Driven Design• https://practicingruby.com/articles/responsibility-centric-vs-data-
centric-design
Control Style• distribution of control responsibilities that results in developing a
control style.• Central• Clustered• Delegated
• https://en.wikipedia.org/wiki/Responsibility-driven_design• Same school of thought as Kent Beck and Ward
Cunningham(http://wiki.c2.com/?ResponsibilityDrivenDesign)
Transaction Scripts• business applications modelled as a series of transactions.• Each transaction will have its own Transaction Script• A Transaction Script organizes all this logic primarily as a single
procedure• although common subtasks can be broken into sub procedures.
• Not (functionally)scalable
Transaction Scripts: Symptoms• AddHandler• RemoveHandler• ViewHandler• PaymentHandler
Domain Model• https://www.cp.eng.chula.ac.th/~wiwat/EAA/EAAdomain.pdf
Fowler Speak: Anemic Domain Model
• Domain objects are just bags of getters and setters• No behavior in Domain objects• a set of service objects which capture all the domain logic. • Services use domain model for data• http://www.martinfowler.com/bliki/AnemicDomainModel.html
invariants• Remember the stack example, similarly maintaining invariant• The responsibility of getting the terms lies with Checkout and not an
external utility/Service
(Application)Services
Application Services (..continued)• This layer is kept thin. It does not contain business rules or knowledge,
but only coordinates tasks • delegates work to collaborations of domain objects in the next layer
down. • The key point here is that the Service Layer is thin - all the key logic
lies in the domain layer.• Domain objects are re-used, services are typically not
Application Services (..continued)• In general, the more behavior you find in the services, the more likely
you are to be robbing yourself of the benefits of a domain model.• If all your logic is in services, you've robbed yourself blind.
Rich Domain Model• https://www.link-intersystems.com/blog/2011/10/01/anemic-vs-rich-
domain-models/• Services in a service-oriented architecture are usually application
services that encapsulate use cases.• The only difference to plain transaction scripts is often that they use
parameter objects that are named after domain objects.
Static Object
Data Driven Responsibility Driven
TransactionScript
Domain Model
Anemic DomainModel
Rich DomainModel
Procedural
Static Object
Data Driven Responsibility Driven
TransactionScript
Domain Model
Anemic DomainModel
Rich DomainModel
Domain Driven Design
Naked Objects
Domain Driven Design• https://en.wikipedia.org/wiki/Domain-driven_design• Entity • Value Object An object that contains attributes but has no conceptual
identity. They should be treated as immutable.• Service• Factory.
Entity• An object that is not defined by its attributes, but rather by a thread
of continuity and its identity.• have life cycles that can radically change their form and content• class definitions, responsibilities, attributes, and associations should
revolve around who they are• Eg. Cart, Checkout, Order, Store
Services• The operation relates to a domain concept that is not a natural part of
an Entity or Value Object• The interface is defined in terms of other elements in the domain
model• The operation is stateless
Services (..continued)• They exist in three layers• Application• Domain• Infrastructure
• http://tinyurl.com/z2yeutt
Application Services• Application Services are the interface used by the outside world,
where the outside world can’t communicate via our Entity objects, but may have other representations of them. • Application Services could map outside messages to internal
operations and processes• communicating with services in the Domain and Infrastructure layers
to provide cohesive operations for outside clients.• Don’t contain any business logic• Not part of domain layer
Domain services• Domain services are the coordinators, allowing higher level
functionality between many different smaller parts. • Part of domain model• Can contain business logic
Factories and Repositories• http://tinyurl.com/jdhuebj• Factory encapsulates the knowledge needed to create a complex
object• Can use FactoryMethod, AbstractFactory or Builder• Can create Entities and ValueObjects
Repositories• To do anything with an object, you have to hold a reference to it. How
do you get that reference?• One way is to create the object• A second way is to traverse an association. You start with an object you
already know and ask it for an associated object.
• Repositories are the second way • Example: StoreRegistry
Naked Objects• https://en.wikipedia.org/wiki/Naked_objects
Take Aways• Domain Model >> Data Model• Domain Objects >> bags of getters and setters• Heart and Brain of your system is Domain Model• Domain Objects(and services) are responsible for all of our business
logic• Entities have identity and continuity• Entities trump Services• Layers preceding Domain Model have as little logic as possible• Domain Objects react to ’business events’ and delegate