12. • Get feedback as early as possible, and work
together
• Prefer encapsulated, loosely coupled
systems for core functionality
• Choose the smallest implementation that
provides a way forward
• Make your code readable, understandable,
and maintainable
13. ...the object-oriented approach
encourages the programmer to place
data where it is not directly
accessible by the rest of the
program. Instead, the data is accessed
by calling specially written functions,
commonly called methods...
http://en.wikipedia.org/wiki/Object-oriented_programming
16. Prefer encapsulated, loosely coupled
systems for core functionality
Choose the smallest implementation that
provides a way forward
Make your code readable, understandable,
and maintainable
22. Moose is a postmodern object
system for Perl 5 that takes the tedium
out of writing object-oriented Perl. It
borrows all the best features from Perl
6, CLOS (Lisp), Smalltalk, Java, BETA,
OCaml, Ruby and more, while still
keeping true to its Perl 5 roots.
http://moose.iinteractive.com/
23. package Point;
use Moose;
has 'x' => (isa => 'Int', is => 'rw', required => 1);
has 'y' => (isa => 'Int', is => 'rw', required => 1);
sub clear {
my $self = shift;
$self->x(0);
$self->y(0);
}
29. package Eq;
use Moose::Role;
requires 'equal';
my $defensive_coderef = sub { ... };
sub no_equal {
my ($self, $other) = @_;
!$self->equal($other);
}
package Currency;
use Moose;
with 'Eq';
sub equal {
my ($self, $other) = @_;
$self->as_float == $other->as_float;
}
31. package MyObject;
use Moose;
use MyLogger;
has ‘logger’ => (
is => ‘bare’,
lazy_build => 1,
handles => [qw/err warn/],
);
sub _build_logger { MyLogger->new }
sub something_worth_logging {
my ($self) = @_;
$self->err(“Hey, there’s a problem!!!”);
}
32. package MyObject;
use Moose;
use MooseX::Types::LoadableClass 'LoadableClass';
has logger_class => (
is => 'ro',
default => 'MyLogger',
isa => LoadableClass,
coerce => 1);
has logger_args => (
is=>’ro’, isa=>‘HashRef’, default=> sub { +{} }
);
has ‘logger’ => (
is => ‘bare’,
lazy_build => 1,
handles => [qw/err warn/]);
sub _build_logger {
my $self = shift;
$self->logger_class($self->logger_args)
->new
}
33. package MyObject;
use Moose;
with 'MooseX::Role::BuildInstanceOf' => {
target => 'Logger'
};
has ‘+logger’ => (handles => [qw/err warn/]);
36. Approach
• Create a Base Class with default
functionality
• Use Roles to allow ‘plugging in’ various
target temporary database types
37. DBIx::Class::Migration
• Make it easy to create deploys and
upgrades for database schemas
• Be flexible but have sane, community
accepted standards
38. Approach
• Create a Base class with lots of delegate
placeholders.
• Create defaults classes that provide
required functionality
39. GeneralAssembly::Guestbook
• A Test Application to Demonstrate Perl to
inspired learners
• Code is probably overkill for the actual
problem
40.
41. My Learnings
• Delegation seems the most normally useful
approach to creating easily testable building
blocks.
• Roles are great for enforcing contracts and
for enhancing objects with cross cutting
functionality.
• (Combine the two)++
42. Summary
• There is no necessary tension between
writing the least code and writing good
code
• Good design lets you evolve over time
without nasty hacks
Editor's Notes
\n
\n
\n
great ideas are simple answers to common problems\n\n
maybe not so simple in the details!\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
great ideas are simple answers to common problems\n\n