Instance Initialization How to ensure that an instance

  • Slides: 34
Download presentation
Instance Initialization How to ensure that an instance is well initialized? Automatic initialize Lazy

Instance Initialization How to ensure that an instance is well initialized? Automatic initialize Lazy initialization Proposing the right interface Providing a default value S. Ducasse 1

Provider Responsibility This is the responsibility of the class to provide well-formed object A

Provider Responsibility This is the responsibility of the class to provide well-formed object A client should not make assumptions or been responsible to send specific sequence of messages to get a working object S. Ducasse 2

A First Implementation of Packet Object subclass: #Packet instance. Variable. Names: ‘contents addressee originator

A First Implementation of Packet Object subclass: #Packet instance. Variable. Names: ‘contents addressee originator ‘ Packet>>print. On: a. Stream super print. On: a. Stream next. Put. All: ‘ addressed to: ‘; next. Put. All: self addressee. a. Stream next. Put. All: ‘ with contents: ’; next. Put. All: self contents Packet>>addressee ^addressee Packet>>addressee: a. Symbol addressee : = a. Symbol S. Ducasse 3

Packet class Definition Packet class is automatically defined Packet class instance. Variable. Names: ''

Packet class Definition Packet class is automatically defined Packet class instance. Variable. Names: '' Example of instance creation Packet new addressee: #mac ; contents: ‘hello mac’ S. Ducasse 4

Fragile Instance Creation If we do not specify a contents, it breaks! |p| p

Fragile Instance Creation If we do not specify a contents, it breaks! |p| p : = Packet new addressee: #mac. p print. On: a. Stream -> error S. Ducasse 5

Problems Responsibility of the instance creation relies on the clients A client can create

Problems Responsibility of the instance creation relies on the clients A client can create packet without contents, without address instance variable not initialized -> error (for example, print. On: ) -> system fragile S. Ducasse 6

Fragile Instance Creation Solutions Automatic initialization of instance variables Proposing a solid interface for

Fragile Instance Creation Solutions Automatic initialization of instance variables Proposing a solid interface for the creation Lazy initialization S. Ducasse 7

Instance Initialization How to ensure that an instance is well initialized? Automatic initialize Lazy

Instance Initialization How to ensure that an instance is well initialized? Automatic initialize Lazy initialization Proposing the right interface Providing a default value S. Ducasse 8

Assuring Instance Variable Initialization How to initialize a newly created instance ? Define the

Assuring Instance Variable Initialization How to initialize a newly created instance ? Define the method initialize Packet>>initialize super initialize. contents : = ‘’. addressee : = #no. Ad S. Ducasse 9

The New/Initialize Couple Object>>initialize “do nothing. Called by new my subclasses override me if

The New/Initialize Couple Object>>initialize “do nothing. Called by new my subclasses override me if necessary” ^ self S. Ducasse 10

(VW) Assuring Instance Variable Initialization Problem: By default new class method returns instance with

(VW) Assuring Instance Variable Initialization Problem: By default new class method returns instance with uninitialized instance variables. In Visual. Works, initialize method is not automatically called by creation methods new/new: . How to initialize a newly created instance ? S. Ducasse 11

new calling initialize Packet new. . . should invoke the initialize method Packet class>>new

new calling initialize Packet new. . . should invoke the initialize method Packet class>>new | inst : = super new. inst initialize. ^ inst Packet class>>new ^ super new initialize; yourself S. Ducasse 12

The New/Initialize Couple Define an instance method that initializes the instance variables and override

The New/Initialize Couple Define an instance method that initializes the instance variables and override new to invoke it. (1&2) Packet class>>new “Class Method” ^ super new initialize (3) Method” Packet>>initialize (4) “Instance super initialize. contents : = ‘default message’ Packet new (1 -2) => a. Packet initialize (3 -4) => returning a. Packet but initialized! Reminder: You cannot access instance variables from a class method like new S. Ducasse 13

One single method application S. Ducasse 14

One single method application S. Ducasse 14

Instance Initialization How to ensure that an instance is well initialized? Automatic initialize Lazy

Instance Initialization How to ensure that an instance is well initialized? Automatic initialize Lazy initialization Proposing the right interface Providing a default value S. Ducasse 15

Lazy Initialization When some instance variables are: - not used all the time -

Lazy Initialization When some instance variables are: - not used all the time - consuming space, difficult to initialize because depending on other - need a lot of computation Use lazy initialization based on accessors Accessor access should be used consistently! S. Ducasse 16

Lazy Initialization Example A lazy initialization scheme with default value Packet>>contents is. Nil if.

Lazy Initialization Example A lazy initialization scheme with default value Packet>>contents is. Nil if. True: [contents : = ‘no contents’] ^ contents a. Packet contents or self contents A lazy initialization scheme with computed value Dummy>>ratio is. Nil if. True: [ratio : = self heavy. Computation] ^ ratio S. Ducasse 17

Better Packet>>contents is. Nil if. True: [contents : = ‘no contents’] ^ contents is

Better Packet>>contents is. Nil if. True: [contents : = ‘no contents’] ^ contents is equivalent to Packet>>contents ^ contents if. Nil: [contents : = ‘no contents] S. Ducasse 18

Instance Initialization How to ensure that an instance is well initialized? Automatic initialize Lazy

Instance Initialization How to ensure that an instance is well initialized? Automatic initialize Lazy initialization Proposing the right interface Providing a default value S. Ducasse 19

Strengthen Instance Creation Interface Problem: A client can still create a. Packet without address.

Strengthen Instance Creation Interface Problem: A client can still create a. Packet without address. Solution: Force the client to use the class interface creation. Providing an interface for creation and avoiding the use of new: Packet send: ‘Hello mac’ to: #Mac Packet class>>send: a. String to: an. Address ^ self new contents: a. String ; addressee: an. Address ; yourself S. Ducasse 20

Examples of Instance Initialization step 1. Sorted. Collection sort. Block: [: a : b|

Examples of Instance Initialization step 1. Sorted. Collection sort. Block: [: a : b| a name < b name] Sorted. Collection class>>sort. Block: a. Block "Answer a new instance of Sorted. Collection such that its elements are sorted according to the criterion specified in a. Block. " ^ self new sort. Block: a. Block step 2. self new => a. Sorted. Collection step 3. a. Sorted. Collection sort. Block: a. Block S. Ducasse step 4. returning the instance a. Sorted. Collection 21

Another Example step 1. Ordered. Collection with: 1 Collection class>>with: an. Object "Answer a

Another Example step 1. Ordered. Collection with: 1 Collection class>>with: an. Object "Answer a new instance of a Collection containing an. Object. " | new. Collection : = self new. Collection add: an. Object. ^new. Collection S. Ducasse 22

Instance Initialization How to ensure that an instance is well initialized? Automatic initialize Lazy

Instance Initialization How to ensure that an instance is well initialized? Automatic initialize Lazy initialization Proposing the right interface Providing a default value S. Ducasse 23

Providing a Default Value Ordered. Collection variable. Subclass: #Sorted. Collection instance. Variable. Names: 'sort.

Providing a Default Value Ordered. Collection variable. Subclass: #Sorted. Collection instance. Variable. Names: 'sort. Block ' class. Variable. Names: 'Default. Sort. Block ' Sorted. Collection class>>initialize Default. Sort. Block : = [: x : y | x <= y] Sorted. Collection>>initialize "Set the initial value of the receiver's sorting algorithm to a default. ” sort. Block : = Default. Sort. Block S. Ducasse 24

Providing a Default Value Sorted. Collection class>>new: an. Integer "Answer a new instance of

Providing a Default Value Sorted. Collection class>>new: an. Integer "Answer a new instance of Sorted. Collection. The default sorting is a <= comparison on elements. " ^ (super new: an. Integer) initialize Sorted. Collection class>>sort. Block: a. Block "Answer a new instance of Sorted. Collection such that its elements are sorted according to the S. Ducasse criterion specified in a. Block. " 25

Invoking per Default the Creation Interface Ordered. Collection class>>new "Answer a new empty instance

Invoking per Default the Creation Interface Ordered. Collection class>>new "Answer a new empty instance of Ordered. Collection. " ^self new: 5 S. Ducasse 26

Forbidding new? Problem: We can still use new to create fragile instances Solution: new

Forbidding new? Problem: We can still use new to create fragile instances Solution: new should raise an error! Packet class>>new self error: 'Packet should only be created using send: to: ' S. Ducasse 27

Forbidding new Implications But we still have to be able to create instance! Packet

Forbidding new Implications But we still have to be able to create instance! Packet class>>send: a. String to: an. Addres ^ self new contents: a. String ; addressee: an. Address raises an error Packet class>>send: a. String to: an. Address ^ super new contents: a. String ; addressee: an. Address BAD STYLE: link between class and superclass S. Ducasse dangerous in case of evolution 28

Forbidding new Solution: use basic. New and basic. New: Packet class>>send: a. String to:

Forbidding new Solution: use basic. New and basic. New: Packet class>>send: a. String to: an. Address ^ self basic. New contents: a. String ; addressee: an. Address Conclusion: Never override basic* methods else you will not be able to invoke them later S. Ducasse 29

How to Reuse Superclass Initialization? A class>>new ^ super new do. That; and. That;

How to Reuse Superclass Initialization? A class>>new ^ super new do. That; and. That; end B class>>force. Client. Interface ^ self basic. New ? ? ? Solution: Define the initialization behavior on the instance side A>>do. That. And. That. End ^ self do. That; and. That; end A class>>new ^ super new do. That. And. That. End B class>>force. Client. Interface ^ self basic. New do. That. And. That. End S. Ducasse 30

Even Better. . . Use initialize But you cannot simply chain the calls. .

Even Better. . . Use initialize But you cannot simply chain the calls. . . so use initialize A>>initialize super initialize. self do. That; and. That; end B>>initialize super initialize. self and. Foo. S. Ducasse 31

Different Self/Super Do not invoke a super with a different method selector. It’s bad

Different Self/Super Do not invoke a super with a different method selector. It’s bad style because it links a class and a superclass. It makes the code difficult to understand This is dangerous in case the software evolves. S. Ducasse 32

Example Packet class>>new self error: 'Packet should be created using send: to: ' Packet

Example Packet class>>new self error: 'Packet should be created using send: to: ' Packet class>>send: a. String to: an. Address ^ super new contents: a. String ; addressee: an. Address Use basic. New and basic. New: Packet class>>send: a. String to: an. Address ^ self basic. New contents: a. String ; addressee: S. Ducasse 33 an. Address

Super is static! With the super foo: A new bar -> 10 B new

Super is static! With the super foo: A new bar -> 10 B new bar -> 10 C new bar -> 10 Without the super foo: S. Ducasse A new bar -> 10 B new bar -> 100 C new bar -> 50 34