Why are we here?
Explore concepts around domain objects
Understand the history of Smalltalk and MVC
Play around with the NakedObjects framework
Smalltalk is...
object-oriented
dynamically-typed
message-passing
reflective
... programming language
... and environment
Current Smalltalk implementations
Amber (runs in Javascript browsers!)
http://www.amber-lang.net/
Squeak
https://en.wikipedia.org/wiki/Squeak
GNU Smalltalk
https://en.wikipedia.org/wiki/GNU_Smalltalk
Concomm Smalltalk (ObjectStudio, VisualWorks)
http://www.cincomsmalltalk.com/main/
Pharo
http://pharo.org/
Smalltalk's history is long and distinguished
began development in 1969
developed at Xerox PARC
invented by Alan Kay (with help from Dan Ingalls)
influenced by Lisp, Simula, Logo, Sketchpad
first release -- Smalltalk-71
first public release -- Smalltalk-80
Smalltalk influenced...
AppleScript
Common Lisp Object System
Dart
Dylan
Erlang
Etoys
Falcon
Smalltalk influenced...
Go
Groovy
Io
Ioke
Java
Lasso
Lisaac
Smalltalk influenced...
Logtalk
NewtonScript
Object REXX
Objective-C
PHP 5
Perl 6
Smalltalk influenced...
Python
Ruby
Scala
Scratch
Self
Began on a bet
can a programming language based on the idea of message passing inspired by Simula be implemented in 'a page of code'?
incidentally, Kay answered that in "a few mornings"
Objects introduced in Smalltalk-80
Smalltalk object can do three things:
hold state (references to other objects)
receive a message from itself or another object
in the course of processing a message, send a message to itself or another object
no difference between values which are objects and primitive types
"in Smalltalk everything is an object"
classes are also instances of objects
Smalltalk incorporated IDE and runtime into one tool
this is the "Smalltalk browser"
objects were visual objects
manipulate the objects to manipulate the environment
image files were of the entire runtime
MVC is a design pattern that appears frequently in GUI systems
Model represents the state
Controller represents the logic
View represents the display/UI
Origins lie in Smalltalk
Models were objects
Controllers were objects
Views were objects
Today, this is an idiom known as "Naked Objects"
MVC showed up in a number of GUI systems
Windows UI frameworks called it "Document/View"
Java Swing built around MVC quite deeply
tables, lists, all used models extensively
even the actual UI code was split along view/controller lines; AbstractButton defined basic button behavior, and deferred to another class to do the actual pixel-drawing work
iOS uses it (ViewControllers are controllers)
In the original MVC...
Models were often connected to more than one View
Controllers coordinated view updates as model changed
Models, Views and Controllers relatively loosely coupled
Web adaptation of MVC changed this to a 1:1 View/Controller
Web views and controllers never reused
Parting thoughts
Models are not necessarily Domain Objects
community is split over this one
Views should not contain "logic"
except for logic that is UI-focused
community is split over this one too
MVC has spawned a lot of similar ideas/patterns
Hierarchical model-view-controller
Model-view-adapter
Model-view-presenter
Model View ViewModel
Observer
Presentation-abstraction-control
Three- or n-tier architecture
Resources
For more details, see
http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
Observer pattern comes from "Design Patterns" (GOF book)
Gamma, Helm, Johnson, Vlissides
Presentation-abstraction-control comes from "POSA 1"
Buschmann, Meuneir, Rohnert, Sommerlad, Stal
In the old days...
objects were intended to be directly user-manipulable things
data directly modified/changed
methods directly invoked
connections directly displayed/modified
... but we have since lost that simple idea
What's wrong with the way we do applications today?
too much complexity in the UI code
too many opportunities to get the business rules wrong
too much time spent building the system
too much effort required to understand/maintain it
New idea: Let the UI center around the objects
"All business logic should be encapsulated onto the domain objects."
"The user interface should be a direct representation of the domain objects, with all user actions explicitly consist in the creating or the retrieving of domain objects and/or invoking methods on those objects."
"The user interface shall be 100% automatically created from the definition of the domain objects."
Benefits:
faster development cycle
greater agility
more user-centric/empowered user interface
easier requirements analysis
Naked Objects frameworks core concepts
Domain Objects
properties
collections
actions
Value types
Non-objects
Factories/Repositories
services
external/system services
ViewModels
Domain objects
domain objects represent the persistent entities described within the system
these are your "plain old objects" (POJOs, POCOs, etc)
typically they intend to represent state plus behavior
state is expressed as properties
behavior is expressed as actions
Properties
represents an element of state in a domain object
typically one of three types
value property (property of value type)
reference property (association to another domain object)
collection property (collection of properties)
properties can have some UI logic or behavior attached to them
control the order in which properties are displayed
trigger behavior when a property is changed
input validation
Actions
actions are methods intended for user invocation
typically these are "just methods" that are discovered
Value types
these are basically non-referenced objects
we care only for their value
they lack a standalone "identity"
embedded "in-place" for storage
Services
services are code that aren't attached specifically to objects
these are often pure logic/behavior/transformational in nature
NakedObject services come in three flavors:
creating/retrieving domain objects (factories/repositories)
provide a bridge to external functionality (external services)
provide functionality shared by multiple domain objects which do not share a common superclass (contributed actions)
Factories/respositories
factory is a service for manufacturing new instances of an object
repository is a service for obtaining existing instances of objects
whether these are the same service is a point of debate
NakedObjects frameworks typically support either style
most often, objects will be found by navigating from other objects
Pet -> Owner doesn't require the use of a repository, for example
External services
bridge to external functionality
such as accessing an email system to send/receive messages
these will vary in size and shape with the external functionality being accessed/used
look to avoid duplicating Naked Object functionality here!
shouldn't need to write a database access service, for example
Contributed actions
a contributed action is an action that is defined on a service but which is presented to the user as an action on an individual domain object (or collection of objects)
these are, effectively, "aspect-oriented" actions applied to Naked Objects
Step 1: Download Template project and docs
NakedObjects GitHub website
https://github.com/NakedObjectsGroup/NakedObjectsFramework
Download the Template project
https://github.com/NakedObjectsGroup/NakedObjectsFramework/blob/master/Template_NOF9/Template_NOF9.zip?raw=true
Download the DeveloperManual for details
https://github.com/NakedObjectsGroup/NakedObjectsFramework/blob/master/Documentation/NOF9DeveloperManual.docx?raw=true
Step 2: Unzip Template solution
Builds in VisualStudio 2015+
Consists of five projects
Model: domain objects and services
Server: RESTful Objects Server
DataBase: Relational database project
SeedData: Seed data for RDBMS
Client: Angular Web/SPA client
Model is where the action is
ships w/Student (object) and ExampleService (service)
Step 3: Build/Run
Server is the Startup project
http://localhost:5000
Server builds the database on demand
EntityFramework bootstrapping
SeedData project initializes the database
Client (Gemini) starts up
http://localhost:5001
Start with "simple" O-O domain class
traditional DDD approach: domain entities
persistable
containing (some) business logic
validating rules
... and so on
Student
public enum Subject { CompSci, Philosophy, BasketWeaving } public class Student { public virtual int Id { get; set; } public virtual string FullName { get; set; } public virtual int Age { get; set; } public virtual Subject Subject { get; set; } public virtual void HaveBirthday() { Age++; } }
Properties
must be virtual
allows for runtime subclassing to provide enhanced functionality
implicitly persisted
three flavors
value property (property of value type)
reference property (property to named/referenced domain object)
sometimes called 'associations' or '1:1 associations'
collection property (preferably ICollection-typed)
'1:n associations'
Actions
public instance method
static, non-public or NakedObjectsIgnore methods will be ignored
actions basically provide behavior
actions can also return a collection of objects
"return all students connected to this student (somehow)"
return an IQueryable if it's a large collection
Student
public class Student { // This property will never be seen in the UI [NakedObjectsIgnore] public virtual int Id { get; set; } // This property will be used for the object's title [Title] public virtual string FullName { get; set; } public virtual int Age { get; set; } public virtual Subject Subject { get; set; } public virtual void HaveBirthday() { Age++; } }
Presentation is derived from class definitions
conventions provide basic user interface
properties are data elements
methods are actions
custom attributes provide (some) UI customization
UI-level validation
UI-level "hints"
Persistence is handled by EntityFramework
a little hidden under the covers
but EF attributes can "flow through"
generally, however, NakedObjects assume they have full control over the persistence repository
in other words, they don't always play nice with brownfield database schema
Object (per-instance) Menus
constructed from
the actions on the object instance
"contributed actions" (more later)
order of menu items controlled by MemberOrder
overridde order/contents by providing
public static void Menu(IMenu menu)
menu accepts action names (matching method names)
Numerous "tweaks" to customize object presentation
Title attribute (or method) customizes the title
absent a title, NOF uses ToString()
Hidden means to hide an attribute from the user
DisplayName provides object type name
use Plural to specify irregular pluralization
MaxLength/MinLength
DescribedAs provides tooltip help
Numerous "tweaks" to customize object presentation
"complementary methods" provide more sophisticated behavior
public void {methodtype}{propertyname}()
Choices() provides dropdown for user (property or parameter)
Modify() invoked when user modifies a field
Validate() provides complex validation
Object lifecycle
transient v persistent
objects begin as transient until persisted
create objects using Container.NewTransientInstance method
transient objects returned to user automatically gain "Save" UI
when the user saves, the object is persisted
programmatically save using Container.Persist method
once saved, objects save themselves henceforth
Object lifecycle methods provide notifications
Created
Loading/Loaded
Updating/Updated
Deleting/Deleted
... more described in NOF Guide
ViewModels provide "views" over domain objects
typically presentation-only
that is, not persisted
for more highly customized presentation
aggregating several related domain entities
reports/dashboards/etc
Services perform three roles
provide means for creating/retrieving domain objects
a.k.a. "factories" or "repositories"
provide a bridge to external functionality
provide shared functionality across multiple domain object classes
Services are plain .NET classes
IDomainObjectContainer holds the key to the environment
dependency-injected
they must be registered in the NakedObjects "Reflector"
this is the discovery tool/process
Template.Server / App_Start / NakedObjectsRunSettings.cs
NakedObjectsRunSettings::Services
services can register actions in "main menus"
NakedObjectsRunSettings::MainMenus
Factories/Repositories
beyond basic CRUD behavior
filtered queries
transactional operations
parameterized construction
Factory/Repository service
public class ExampleService { public IDomainObjectContainer Container { set; protected get; } public Student CreateNewStudent() { return Container.NewTransientInstance<Student>(); } public IQueryable<Student> AllStudents() { return Container.Instances<Student>(); } public IQueryable<Student> FindStudentByName(string name) { return AllStudents().Where(c => c.FullName.ToUpper().Contains(name.ToUpper())); } }
Shared logic
used in place of static methods
domain entities can simply use the associated service
think "Utils" classes found in every codebase
External functionality
basically just another service
but with the emphasis being to access external services/APIs
this can range as far and as wide as you need it to go
Dependent services are dependency-injected
for either domain entities or other services
place a public-get/protected-set property of the desired type
Authentication
asking clients to prove who they claim to be
presentation/validation of credentials
Authorization
restricting access/actions by users
examining permissions at runtime
Authentication: client
client auth leverages Auth0 (http://www.auth0.com)
create free account and configure application in Auth0 UI
configure client to challenge for creds
client project: config.json
"authenticate": true
"authDomain": (from Auth0)
"authClientId": (from Auth0)
Authentication: server
examine RestfulObjectsConfig::RestPostStart
add Authorize to RestfulObjectsController
add keys to web.config (values from Auth0)
auth0:ClientId
auth0:ClientSecret
Authorization
NOF supports fine-grained authorization
whether a user may view and/or edit individual properties on object types, and whether a user may invoke individual actions on services
attribute-based authorization
custom authorization
Auditing
want to know who did what to which object and when?
NOF supports auditing
create (and register) an IAuditor-inheriting service
callbacks for action invocation (on object or service) and object update/persist
Reading
Richard Pawson's PhD thesis
http://downloads.nakedobjects.net/resources/Pawson%20thesis.pdf
"Naked Objects"
http://www.nakedobjects.org/book/
"DDD Using Naked Objects", by Dan Haywood (Pragmatic Bookshelf)
http://www.pragprog.com/titles/dhnako/domain-driven-design-using-naked-objects
So... where are we?
Who is this guy?
Architect, Engineering Manager/Leader, "force multiplier"
Principal -- Neward & Associates
http://www.newardassociates.com
Educative (http://educative.io) Author
Performance Management for Engineering Managers
Author
Professional F# 2.0 (w/Erickson, et al; Wrox, 2010)
Effective Enterprise Java (Addison-Wesley, 2004)
SSCLI Essentials (w/Stutz, et al; OReilly, 2003)
Server-Based Java Programming (Manning, 2000)