Traits composition
Upcoming SlideShare
Loading in...5
×
 

Traits composition

on

  • 2,154 views

Traits offer an alternative solution to inheritance that is particularly suited to class-less languages like Javascript. With this approach, the aspects of instance generation and units of reuse are ...

Traits offer an alternative solution to inheritance that is particularly suited to class-less languages like Javascript. With this approach, the aspects of instance generation and units of reuse are clearly separated while providing methods of composition that are functionally similar to multiple inheritance. Troublesome multiple inheritance issues like the diamond problems are avoided by keeping traits stateless. Any state must be stored in the instance that inherits from the trait.

Statistics

Views

Total Views
2,154
Views on SlideShare
2,152
Embed Views
2

Actions

Likes
0
Downloads
11
Comments
1

1 Embed 2

http://www.linkedin.com 2

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

CC Attribution License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

11 of 1

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • Hi Marielle,

    as addition to your talk/slides I'd like to point to 'Stateful Traits' that are acknowledged and described by academic papers as far back as 2006 - e.g.

    > Alexandre Bergel, Stéphane Ducasse, Oscar Nierstrasz
    > and Roel Wuyts. Stateful Traits. In Advances in Smalltalk —
    > Proceedings of 14th International Smalltalk Conference (ISC 2006),
    > LNCS 4406 p. 66—90, Springer, Berlin Heidelberg, August 2007.

    - http://scg.unibe.ch/archive/papers/Berg07aStatefulTraits.pdf
    - http://scg.unibe.ch/scgbib?query=traits


    And if it comes to JavaScript, due to its core language features like first class functions, closures and delegation, it has a natural predisposition adapting to a lot of Role-based object composition approaches like Mixins, (stateful) Traits and most recently Talents too.

    - http://peterseliger.blogspot.de/2014/04/the-many-talents-of-javascript.html#the-many-talents-of-javascript

    --
    Peter
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

Traits composition Traits composition Presentation Transcript

  • When “is a” and “has a” wouldn’t do!Traits composition
  • Who? Marielle Lange @widged Flex developer for Academic a living (since background (last at 2008) “The Institute for Adaptive and Javascript & jQuery Neural
  • Traits? • Clearly separates issues of instance generation and units of reuse • Composition mechanisms • Divorced from the inheritance hierarchy ➡ Avoid difficulties experienced with multiple inheritance. • Impose no composition order ➡ Avoid difficulties experienced with mixins. • Introduced in SmallTalk. Particularly suited to class-less languages like Javascript. Also found in class-based ones. Recently added to PHP. Supported in Scala (Java)
  • Focuses on RulesInput Output Rules State
  • Object-OrientedSpirit of the law (hereOO language) vs letter of the law
  • Object Oriented An Objects and classes approach allows for the design of components that are fully re-usable across projects and sometimes across programming frameworks.
  • Objects Reference to objects that are meant to mimic real world behaviour. • Intuitive and consistent abstractions of the problem being solved throughout the analysis, design, implementation, and maintenance phases of development. • Provision for testing and the ability to embrace change.
  • Classes (Templates for objects) • Conflicting purposes • As generators of objects, classes must be complete and monolithic. • As units of reuse via inheritance, they should be small, fine-grained, and possibly incomplete. James Gosling, creator of Java, once said that if he could do Java over again, he
  • Fragile inheritance chainsIs a Bird lacks flyingHas wings code ➡ flightless duplication bird is a FLBTCS? ➡ flightless has a swim manager?Has buoyant bird,body implements swimmer
  • Multiple inheritance Bird Swimmer Flyer
  • Traits composition Bird BirdMan can swim Bird can swim (swim trait) can fly can swim can fly Traits are coherent collections of methods that can be reused anywhere in the
  • Re-use, no • Halfway between an interface and a class. • Like interfaces, they define behaviors that the objects can implement. Unlike interfaces, the definition includes the actual implementation. • Like classes, they provide method implementations that can be acquired by objects. However, they are stateless (they don’t include instance variables), not bound to a hierarchy (inheritance chain) and do not have to be complete (they do not have to define all
  • Languages limitations • Straightforward to implement in languages like javascript that treat functions as first class objects. • var a = function() {} ➡ Functions can be passed as arguments to other functions, returning them as the values from other functions, and assigning them to variables or storing them in data structures. • Require language modifications or preprocessing solutions for languages that
  • Traits 101
  • Set of methods • A trait includes: • Only methods • No state (no instance variable)
  • Example <?php trait HelloWorld {     public function sayHello() {         echo Hello World!;     } } class Greeter {     use HelloWorld; } $o = new Greeter(); $o->sayHello(); // =>Hello World! ?> Adapted from: http://php.net/manual/en/language.oop5.traits.php
  • Composition Rules 1. When a class uses a trait, the behaviour provided by the trait gets incorporated (flattened) into the class. This means that the semantics is basically the same as if the services (methods) provided by the trait were implemented in the class itself.
  • Example trait HelloWorld {     public function sayHello() { Different from a         echo Hello World!;     } } class UniverseGreeter { delegate in     public function sayHelloUniverse() {         echo Hello Universe!; the decorator     } } pattern class Greeter {     use HelloWorld;     $universeDelegate = new UniverseGreeter();     public function sayHelloUniverse() {           echo $universeDelegate->sayHello();     } } $o = new Greeter(); $o->sayHello(); // =>Hello World! $o->sayHelloUniverse(); // =>Hello Universe! Adapted from: http://php.net/manual/en/language.oop5.traits.php
  • Composition Rules (ctnd) 2. Methods defined in a class take precedence over methods provided by a trait (any trait method can be overridden by a method with the same name).
  • Example Class <?php trait HelloWorld {     public function sayHello() {         echo Hello World!;     } } class TheWorldIsNotEnough {     use HelloWorld;     public function sayHello() {         echo Hello Universe!;     } } $o = new TheWorldIsNotEnough(); $o->sayHello(); // Hello Universe! ?> source: http://php.net/manual/en/language.oop5.traits.php
  • Composition Rules (ctnd) 3. Composition order is irrelevant. All the traits have the same precedence, and hence conflicting trait methods must be explicitly disambiguated.
  • Example Conflict <?php trait A { class Talker {     public function smallTalk()      use A, B { {         B::smallTalk insteadof A;         echo a;         A::bigTalk insteadof B;     }     }     public function bigTalk() { }         echo A;     } class Aliased_Talker { }     use A, B {         B::smallTalk insteadof A; trait B {         A::bigTalk insteadof B;     public function smallTalk()          B::bigTalk as talk; {     } }         echo b; The composer has full     }     public function bigTalk() { control over the ?>         echo B;     } composition } Sum, override, exclusion, aliasing. Source: http://php.net/manual/en/language.oop5.traits.php
  • Incompleteness • Traits don’t have to be complete • Traits can require methods used by, but not implemented in, a trait. • It is the class responsibility to provide an implementation for every service required by any of the used traits (glue code in the class itself, in a direct or indirect super-class, or in another trait that is used by the class).
  • Example Requires <?php Traits can trait Hello {     public function sayHelloWorld() {         echo Hello.$this->getWorld();     }     abstract public function getWorld(); access state } indirectly, class MyHelloWorld {     private $world; through     use Hello;     public function getWorld() {         return $this->world; required     }     public function setWorld($val) { accessor         $this->world = $val;     } services. } ?> source: http://php.net/manual/en/language.oop5.traits.php
  • Composite traits • Traits cannot define a superclass. • However, in some languages, it is possible to define composite traits. That is, traits that are composed of other traits.
  • Traits forenterprise
  • Language support Supported in Smalltalk, PHP, Scala (Java), C#, JavaScript
  • Objects with traits • Intuitive and consistent ✓ abstractions of the problem being solved throughout the analysis, design, implementation, and maintenance phases of development. ✓ • Provision for testing and the
  • Duplication of code • In languages that don’t treat functions as first class objects, traits are typically flattened into a class by compiler assisted copy and paste. • Duplication of code to avoid runtime overhead. • In essence, stateless traits are incomplete. They necessarily encode dependency on state in terms of required accessors methods (getters, setters) that the composing class must define ➡ Each client class has to implement boilerplate glue code.
  • Tight coupling to • A trait solution tightly couples the trait implementation to the using class. This can actually reduce the reusability and utility of the class itself. • These are problems that we normally use design patterns to solve (such as Decorator, Composite and Bridge). ➡ Encourages a quick solution were refactoring should be considered. (source: Traits are the new Eval)
  • Fragile to change • Fragile to incremental or unanticipated change • Changing the signature of a trait method will impact all the clients that use the method. • Adding or deleting methods provided by a trait may well impact clients by introducing new conflicts or requirements. • Adding new state requirement in a trait will demand new accessors in all client classes. (source: Stateful traits, PDF)
  • Accessors break encapsulation • Traits tend to unnecessarily expose information. • Traits methods used in client-classes must be public. • A client class using a trait get to see all methods, and not just the ones that are truly its responsibility to implement. • The glue code in the class, must be public. If traits require accessors to access state (i.e., instance variables), then classes using these traits must provide public accessors to the missing state.
  • Initialization • Since traits cannot contain state, variables cannot be declared directly in the trait. Accessors for that variable are made required methods instead. • Where should variables be initialized? • In the class using the trait? • In the trait and pushed into the class via a required setter?
  • Trait modification • In dynamical languages, like JavaScript, potential for the trait to be modified after it has been imported.Core.clone = function(obj) { If you compose a return ns.Core.extend({}, obj);} trait into your class,Core.extend = function(obj, added) { for (key in added) { then add a method if (added.hasOwnProperty(key)) { obj[key] = added[key]; to the trait at run } } time, the method will return obj;} not be available to your class.
  • New Tools Required
  • Horizontal • Representations of single inheritance class hierarchies are working well in IDEs. • Traits offer a new orthogonal relation between classes and traits. • The addition of breadth makes it harder to represent and understand. (source: Traits are the new Eval)
  • Composition Explorer • Keeping track of the dependencies between traits and classes. • How the responsibilities of a class are decomposed into several traits and how these traits are glued together in order to achieve the required behaviour. • How the class meets the requirements of its component traits: the provided and required methods, the overridden methods, and the glue methods. (source: Traits: Composable Units of Behaviour*, PDF)
  • Edit time warnings • If a modification causes a new conflict or an unspecified requirement anywhere in the system, the affected classes and traits are automatically added to a “to do” list. • The tools should announce a conflict if a method of the same name and signature is obtained (source: Traits: Composable Units of Behaviour*, PDF)
  • Glue code generation • Generation of required methods that correspond to instance variable accessors. • preferably avoiding actual duplication. • Semi-automated solutions to conflict resolution. • List of alternative implementations • Choosing one generates the composition clause that excludes the others, and thus eliminates the conflict. (source: “ Traits: Composable Units of Behaviour* “ and “Stateful Traits “)
  • Debugging • Traits should be represented in the debugger, so that a programmer can easily map code being executed to the actual source code (written with traits). (source: Adding Traits to (Statically Typed) Languages, PDF)
  • Runtime reflection • Many programming languages allow to reflect and sometimes even manipulate the program being executed. • It is important that traits are correctly represented in the reflective infrastructure of the language, so that one can for example ask which methods are provided by a certain trait or which traits are used by a certain class. (source: Adding Traits to (Statically Typed) Languages, PDF)
  • Thoughts?
  • “can do” • Thinking in terms of what an instance “can do”, in addition to the familiar “is a”and “has a” modes of composition. • Keeping in mind that you don’t necessarily have to encapsulate variables and methods in a class.
  • Functional PgLook at Function.prototype.partial = function(){   var fn   = this,Partials       args = Array.prototype.slice.call(arguments);   return function(){     var arg = 0;     for ( var i = 0; i < args.length &&            arg < arguments.length; i++ )       if ( args[i] === undefined )         args[i] = arguments[arg++];     return fn.apply(this, args);   }; };   String.prototype.csv2 = String.prototype.split.partial(/,s*/); ("John, Resig, Boston").csv2() => ["Resig"] 
  • Thanks!@widged