Software Development: Beyond Training wheels

Preview:

Citation preview

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