Graduate Program KB

A model expressed in software

  • Associations between objects are simple to conceive and draw, but harder to implement
  • Distinctions among three patterns of model elements which express the model
    1. Entities
    2. Value objects
    3. Services

Associations

  • For every traversable association in the model there is a mechanism in the software with the same properties
  • A model that shows an association between a customer and a sales representative represents two things
    1. Abstracts a relationship deemed relevant between two people
    2. Corresponds to an object pointer between two java objects (or some other implementation)
  • e..g a one-to-many association might be implemented as a collection in an instance variable
    • might not be this direct, no collection, accessor queries a db
  • Design has to specify a traversal mechanism
  • In real life lots of bidirectional many-to-many relationships
    • Tends to be true of early forms of a model as we brainstorm
    • Complicate implementation and maintenance
    • Communicate little about the relationship
      • Arrows in both directions look the same
    • Both objects can only be understood together
  • At least 3 ways of making more tractable
    1. Impose a direction
    2. Add a qualifier, reducing multiplicity
    3. Eliminating nonsensical associations
  • We seldom start with the name George Washington and ask which country he was president of
    • On direction more important country -> president
    • Keeps person independent of president
  • Deeper understanding leads to a qualified rule
    • Only one president at a time
    • country -period> president
  • Constraining associations makes them more communicative and simple to implement
    • Significance to bidirectional
  • Brokerage account, investment
    • multiple brokerage accounts with multiple investments
    • Only one investment per stock - add constraint

Entities

  • Mistaken identity in software system leads to data corruption and data entries
  • Many things are defined by identity and not an attribute
  • A person has an identity starting at birth and stretching beyond death
    • Persons attributes change and eventually disappear
  • User could be used across multiple systems with different representations
    • Still need to identify
  • Identity has to be matched between multiple implementations of the objects, its stored forms, and real-world actors
    • Attributes may not match
    • Two customers may have the same name
    • May have entered an address update in one system which is still being propagated
  • Entity is a thread of identity which runs through time and across distinct representations
    • Could be anything, person, city, cat, lottery ticket, bank transaction
  • Not all objects in the morel are entities with meaningful identities
  • Common for identity to be significant outside software system e.g. check number
    • Not always
  • When an object is distinguished by identity make this primary to the definition in the model
  • Keep class definition simple and focused on life cycle continuity and identity
  • Define a means of distinguishing each object regardless of form or history
  • Define an operation that is guaranteed to produce a unique result for each object - e.g. attaching a unique symbol
  • Model must define what it means to be the same thing
  • Application for booking seats in a stadium may treat seats and attendees as entities
    • Assigned seating: each ticket has a seat number, identity
    • General admission: No need to distinguish seats
      • Even if they have numbers written on them, irrelevant to model
      • Error to make them entities

Modeling entities

  • Best if kept spare
  • Reduce to most intrinsic characteristics used to identify, or commonly used to find and match
  • Only behaviour that is essential to the concepts and attributes required by that behaviour
  • Remove behaviour and attributes into other objects associated with the entity
  • Some will be other entities, other value objects
  • Coordinate the operations of objects they own
  • CustomerID is only identifier of customer, but often queried by name, phone, address
    • May include in the entity
  • Identity operation
    • May create object multiple times - loaded from db
    • Could have multiple versions - updates propagating through distributed db
  • Can try to make a unique key from combination of attributes that can be constrained to be unique
    • Name changes, need to be consistent over life cycle
  • Attach each a unique symbol
    • Designated immutable
  • ID may not need to be seen by user
    • But might in some cases - tracking number for package
  • May need to be unique outside the system's boundaries
    • Medical records exchanged between hospitals
    • May use an identifier from another institution like a government agency
    • Not foolproof
  • If ID or operations aren't a meaningful distinction in the domain it confuses matters more
  • Identity assigning operations often involve human input
    • May offer likely matches and leave it to the user to confirm

Value objects

  • Natural to consider assigning identity to everything
  • System has to cope with all that tracking
  • Rules out performance optimizations
  • Effort is required to define meaningful identities and work out foolproof ways to track across distributed systems
  • Muddles the model, making all objects look the same
  • Not just the absence of identity
    • describe things
    • descriptive aspect of the domain
  • Only care about what they are, not who they are
  • Colours, strings, numbers, amounts
  • Can be an assemblage of other objects
    • house plan, window style
  • Can reference entities
    • Route could reference roads, cities
  • Often passed as parameters in messages between objects
  • Frequently transient, created for an operation and discarded
  • Attributes of identities, person is an entity, but name is a value
  • Treat value objects as immutable
  • Avoid design complexity needed to maintain entities
  • Should form a cohesive whole, Address is a street, city, state

Designing value objects

  • Don't care which instance of a value object we have
  • Design freedom to simplify design or increase performance
  • Need to make choices about copying, sharing and immutability
  • Name object is interchangeable, can copy between people
  • Two person objects may not need their own name instances
    • Pointer to same object
    • Changing it for one person would change it for the other
    • Make immutable
  • Same issue when passing attribute to another object
    • Immutable or make copy
  • Extra objects for performance tuning can be important - lots of value objects
  • If each electrical outlet in a house plan is an entity, could be hundreds in one plan
    • Make interchangeable value objects
    • flyweight
  • Copying vs sharing
    • Copying can clog the system, but sharing can slow down a distributed system - locking
    • Sharing better left to cases where it is most valuable and least troublesome
      • Saving space or object count in db is critical
      • communication overhead is low
      • shared object is strictly immutable
  • Mutable objects can be freely shared
  • When to allow mutability
    • If it changes frequently
    • If object creation or deletion is expensive
    • If replacement will disturb clustering
    • If mutable it must not be shared

Tuning a db with value objects

  • db places data on a physical disk
  • Takes time for physical parts to move around and read
  • Attempt to cluster physical addresses so that related data can be fetched in a single operation
  • If referenced by many objects, will not be located near most of them
  • Making a copy allows it to be stored on the same page as each entity - denormalization
  • Also storing the value object on another server requires sending a request to fetch

Designing associations which involve value objects

  • Bidirectional associations between value objects make no sense
    • Meaningless without identity
  • If it seems like you need a bidirectional association one or both should probably be an entity with an identity that hasn't been recognized yet

Services

  • Operations which don't fit on a single object
  • Forcing the behaviour on an object loses it's conceptual clarity and becomes hard to understand
  • These operations usually draw together many domain objects
    • Many responsibilities
  • Sometimes end up as a domain object with the name Manager
    • No state or meaning beyond operation they host
  • Some concepts aren't natural to model as objects
  • Service is an operation offered as an interface that stands alone in the model without any state
  • Named for an activity instead of an entity - verb, not noun
  • Still have defined responsibility and interface as part of the domain model
  • Operation names should be from ubiquitous language
  • Don't strip all behaviour off entities and domain objects
  • Three characteristics for a good service
    1. Operation related to a domain concept that is not naturally a part of an entity or value object
    2. Interface is defined in terms of other elements of the domain model
    3. Operation is stateless
    • Any client can use any instance without regard to its history
    • Execution will use state available globally and possibly have side effects
    • Does not hold its own state which affects its behaviour

Services and the Domain Layer

  • Most services discussed in the literature are part of the infrastructure layer
    • General design pattern
  • Need to distinguish
  • Bank send emails when a customer's balance drops below a certain amount
    • Infrastructure service: from email program
    • Application layer: orders a notification
    • Domain layer: determines if the account falls below the threshold
      • Might noe be a service, more appropriate for the account entity
  • If a service was created to transfer funds it would belong in the domain layer
  • Technical infrastructure services lack any business meaning
  • Services act like scripts that organize the potential of the domain to get something done
  • Entities and value objects are often too fine grained to provide convenient access to the domain layer
    • Fine line between domain and application
  • Importing and exporting transactions to spreadsheet - application, no meaning of file formats in the domain of banking
  • Transferring between accounts encodes significant business rules
    • Awkward to put on accounts since it interacts with multiple as well as global business rules
  • TODO

Granularity

  • Decoupling clients from entities and value objects
  • Medium grained services can be easier to reuse, encapsulate significant functionality into a simple interface
  • Fine grained objects can lead to knowledge leaks from the domain layer into the application layer

Access to services

  • Means of providing access is not as important as the design decision to carve off specific responsibilities
  • A doer object may be satisfactory
  • A simple singleton could provide access
  • Coding conventions can make it obvious that these are just delivery mechanisms for service interfaces
  • Only use elaborate architectures when necessary e.g. to distribute the system

Modules

  • Give two views of the model
  • Can look at detail in a module without being overwhelmed
  • Can look at relationships between models without interior detail
  • Should emerge as a meaningful part of the model
  • Not just code being divided into modules - concepts
  • Low coupling between modules, high cohesion within
    • Particularly important for larger scale design
  • When two elements are separated into modules relationship becomes less direct
    • Increases overhead of understanding
    • low coupling between modules reduces that cost
  • High cohesion within a module allows work to concentrate within a module
  • Should coevolve with smaller elements
  • Typically chosen to organize an early form of objects
    • But then they tend to change in ways that keep them part of a particular module
  • Refactoring modules is more work than classes
    • But letting modules reflect changing domain allows objects within them to evolve
  • Communication mechanism - meaning of the objects being partitioned needs to drive the choice of modules
    • Telling developers to think about them together
  • Module names enter ubiquitous language

Agile modules

  • Changing modules requires widespread updates to the code
  • Can be disruptive to team communication and cause problems with tools e.g. source control
  • Modules typically reflect an earlier form of the model than classes
  • Inevitable early mistakes lead to high coupling between modules
    • Makes refactoring harder, makes problem worse
  • Need to bite the bullet
  • Look for ways to minimize the work of refactoring modules
  • Java requires import of specific classes, even though modeler thinks of packages as depending on other packages
    • Still need to import into specific classes
    • But can import an entire package

Infrastructure driven packaging

  • Tiered architectures can fragment the implementation of model objects
  • Some frameworks cause this by spreading the responsibilities of a single object over multiple objects and placing them in separate packages
  • e.g. J2EE data and data access into entity bean, business logic into session bean
    • Often separated into different packages
  • Lowers cohesion
  • Each conceptual object broken into 4 tiers
    1. data persistence
    2. behaviour intrinsic to object in all situations
    3. application specific functionality
    4. decoupled public interface
    • bit too complicated, but each was well defined
    • tidiness to separation of concerns
      • Helped at times - moving data persistence removed clutter
    • But framework required separate packages with a particular naming convention
      • Developers tended to avoid making too many modules (multiplied by 4)
      • Too hard to refactor
    • Finding all data and behaviour that made up a single object was too hard - combined with indirectness of layering
    • Won't go into solutions - book is not on framework design
      • But not compromising the model is more important than this separation
  • Infrastructure packaging schemes impose two costs
    1. if conventions pull apart domain elements then the code no longer reveals the model
    2. Only so much partitioning a mind can stitch back together
    • If framework uses it all up, none is left for the domain
  • Keep things simple
  • Unless need to distribute code keep all code that implements a single conceptual object in the same module if not object
  • Use packaging to separate domain layer
  • Leave as much freedom as possible to domain developers to package in a way that supports the model
  • Generated code is better to put into a separate package so it doesn't clutter the elements developers actually need to work with

Modelling paradigms

  • Entities, value objects, services, modules provide building blocks for an object model
  • Model driven design oes not mean forcing everything into an object mold
  • There are other paradigms such as rules engines
    • Need to make pragmatic tradeoffs
    • means to the end of model driven design, not alternatives
  • Dominant paradigm is object oriented design

Why object paradigm predominates

  • Balance of simplicity and sophistication
  • Too esoteric -> not enough developers will master it
  • Rich enough to capture important domain knowledge
  • Circumstantial advantages
    • maturity, widespread adoption
    • mature infrastructure
    • tool support
    • most integration problems solved for objects
  • Novel paradigm may be unable to find developers
  • Example
    • Project used an OO database which was new at the time
    • Gradually realized that the test data was using a significant portion of the DBs capacity
    • Production would have a lot more data
    • Production would have a higher transaction volume
    • Brought in one of the few people who understood the new technology
    • Three problems
      1. Off the shelf infrastructure provided with the DB didn't scale to their needs
      2. Storage of fine grained objects is more costly than they realized
      3. Parts of the object model had a tangle of interdependencies that contention was a problem with a small number of concurrent transactions
    • With expert help replaced the off the shelf infrastructure
    • Found models that worked better with the technology instead of storing lots of fine grained objects
    • Deepened thinking about limiting the web of relationships in the model and decoupling
    • lots several months in this recover - in addition to earlier months going down the failed path
  • Now OO technology is relatively mature
  • Common infrastructure works with off the shelf solutions
  • Critical tools come from major vendors or stable open source projects
  • infrastructure pieces are widely used with documentation, books, and people who understand them
  • Other paradigms don't have this maturity
  • Won't be locked into object based systems because object bases systems are widely used and integration tools are likely available
  • Domains that aren't natural to model as objects
    • intensely mathematically
    • dominated by global logical reasoning

Nonobjects in an object world

  • Domain model doesn't have to be object based - there are model driven designs written in prolog

    • Model made up of logical rules and facts
  • Model paradigms are conceived to address ways people think about domains

  • Models are shaped by the paradigm

  • There are likely to be parts of the domain that are better expressed in a paradigm other than the dominant one

    • When there's just a few developers can live with a few awkward objects
    • When different major parts of the domain it's appealing to use a mix of tools and paradigms
    • When the interdependence is small a subsystem in the other paradigm can be encapsulated
      • e.g. complex math calculation called by an object
    • Other times more intertwined
      • e.g. Interactions of objects depends on mathematical relationships
      • Motivates integration into object systems of non object components such as business rules engines and workflow engines.
    • Most systems must use non object infrastructure like rdbms

    Sticking with model driven design when mixing paradigms

  • Rules engines are common

    • A knowledge rich domain model probably contains explicit rules
  • Object paradigm lacks specific semantics for stating rules and their interactions

  • Rules can be modelled as objects

    • But encapsulation makes it apply global rules across the whole system
  • Rules engine technology is appealing because it promises to provide a more natural and declarative way to define rules

  • Logic paradigm is well developed and powerful - seems like a good complement to strengths and weaknesses of objects

  • Doesn't always work out

    • Some products just don't work well
    • Some lack a seamless view that can show the relatedness of model concepts between the two implementation environments
    • Common outcome is program fractured in two
      1. static data storage system using objects
      2. ad hoc rules processing application that's lost all connection to the object model
  • Need to continue thinking in terms of models while working with rules

  • Need to find a single model that works with both paradigms

    • Not easy but should be possible is the rules engine allows an expressive implementation
    • Otherwise data and rules become unconnected
  • Most effective tool for holding the parts together is a robust ubiquitous language

    • Consistently applying names across the two paradigms
  • While model driven design does not have to be object oriented it does depend on having an expressive implementation of the model constructs

    • Unexpressive implementation negates the advantage of an extra paradigm
  • Rules of thumb

    1. Don't fight the implementation paradigm
    • There's always another way to think about the domain
    • Find model concepts that fit the paradigm
    1. Lean on the ubiquitous language
    2. Don't get hung up on UML
    • Focus on UML can lead people to distort the model to what can be easily drawn
    • e.g. UML fetuses for representing constraints are not always sufficient
    • Other types or drawing or english descriptions can be better than trying to force into UML
    1. Be skeptical
    • Is a tool really pulling its weight
    • Just because you have some rules, doesn't necessarily mean you need the overhead of an entire rules engine
    • Rules can be expressed as objects
  • Should exhaust the options of the dominant paradigm before trying to mix

  • Relational paradigm is a special case