Layers of Smalltalk Application


Published on

Published in: Technology
  • Be the first to comment

  • Be the first to like this

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • Layers of Smalltalk Application

    1. 1. Dependence Management <ul><li>Bob Martin says “Object-oriented programming is dependence management.” </li></ul><ul><li>See his “Design Principles and Design Patterns” at </li></ul><ul><li> </li></ul>
    2. 2. Dependence <ul><li>How can one package depend on another? </li></ul><ul><ul><li>Reuse a class </li></ul></ul><ul><ul><ul><li>By inheritance </li></ul></ul></ul><ul><ul><ul><li>By instantiation (direct reference) </li></ul></ul></ul><ul><ul><li>Reuse a variable </li></ul></ul><ul><ul><li>Reuse a method? </li></ul></ul>
    3. 3. Dependence <ul><li>If package A depends on package B then you can’t run the tests for A unless you also have B. </li></ul><ul><li>“A depends on B” means you can’t use A unless you have B. </li></ul><ul><li>“Package A depends on package B” means that something in A depends on something in B. </li></ul>
    4. 4. Cycles of dependence <ul><li>If package A depends on package B then package B should NOT depend on package A. </li></ul><ul><li>If classes C and D both depend on each other, put them in the same package. </li></ul>
    5. 5. Eliminating dependence <ul><li>The Observer pattern eliminates dependence. </li></ul><ul><li>Suppose that “FBIAgent” is an observer of Mobster. Mobster is a subclass of Model, so it can have observers. Class FBIAgent probably depends on class Mobster, but Mobster does not depend on FBIAgent. </li></ul>
    6. 6. Observer Pattern Observer update: Subject addDependent: removeDependent: changed: Mobster robBank driveCar FBIAgent update: observer/ dependent model *
    7. 7. Smalltalk base library GUI library Application Application GUI SUnit tests
    8. 8. Abstract Server <ul><li>Bob Martin’s name for “depend on an interface, not on a concrete class”. </li></ul>Interface Client Server Creation script Consumer <<interface>> Resource Manager ResrcMgr1
    9. 9. Adapter <ul><li>Intent: Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces. </li></ul>Adaptee Adapter Target
    10. 10. Adapter Target Request() Client Adapter Request() Adaptee
    11. 11. Adapter <ul><li>Allows client and adaptee to be unchanged </li></ul><ul><li>Adapter is usually ugly </li></ul>Client Adaptee Adapter
    12. 12. Mediator Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently. Example: Insurance policies must be approved before they are issued. There is a procedure (which can change over time, and which is different for different kinds of policies) for approving a policy. This procedure must interact with work queues of managers and with the history that is kept on the customer. Instead of putting this procedure in the insurance policy, put it in a separate object that is easy to change. (This is a “business process”)
    13. 13. Not Mediator CustomerHistory InsurancePolicy Worker
    14. 14. Mediator Procedure CustomerHistory InsurancePolicy Worker Mediator Colleagues If interaction is main thing that changes, then make the interaction be an object. Colleague classes become more reusable. Mediator is the non-reusable part.
    15. 15. Mediator Procedure CustomerHistory InsurancePolicy Worker Business Rule Domain Objects Mediator Colleagues
    16. 16. Application Model <ul><li>Mediator between widgets and domain model. </li></ul>PayrollSystemInterface ListView TextView Employee PayrollSystem
    17. 17. Façade <ul><li>Provide a unified interface to a set of interfaces in a subsystem. Define a higher-level interface that makes the subsystem easier to use. </li></ul>Facade
    18. 18. The Compiler Scanner Return Expression SmalltalkExpression Compiler compile evaluate CompiledMethod AssignmentExpression Message Expression ... Parser
    19. 19. Creational Patterns <ul><li>Factory Method </li></ul><ul><li>Factory Object </li></ul><ul><ul><li>Abstract Factory </li></ul></ul><ul><ul><li>Builder </li></ul></ul><ul><ul><li>Prototype </li></ul></ul><ul><li>Singleton </li></ul>
    20. 20. Factory Method <ul><li>Don't (call constructor / send message to class) directly. </li></ul><ul><li>Make a separate function / method to create object. </li></ul><ul><li>How to do it: </li></ul><ul><ul><li>Find every class name in “producer” </li></ul></ul><ul><ul><li>Extract it (or perhaps “CN new”) into a method </li></ul></ul>
    21. 21. Factory Method <ul><li>Results: </li></ul><ul><ul><li>Localizes dependencies </li></ul></ul><ul><ul><li>Modules become less coupled </li></ul></ul><ul><ul><li>Reduces coupling </li></ul></ul><ul><ul><li>Can lead to parallel class hierarchies </li></ul></ul>
    22. 22. Factory Method Producer doSomething ConcreteProducer createXX createXX ^XX new doSomething … self createXX ... XX
    23. 23. Factory Object <ul><li>Problem with factory method -- have to create subclass to parameterize. </li></ul><ul><li>Often end up with parallel class hierarchies. </li></ul><ul><li>Example: subclass of Tool for each figure you want to create </li></ul><ul><li>Alternative: parameterize CreationTool with object that creates figure </li></ul><ul><li>Smalltalk automatically creates a factory for every class, the Class! </li></ul><ul><li>(Note: Factory Object is generalization of Abstract Factory,Builder, and Prototype. It is not in the book.) </li></ul>
    24. 24. Applicability <ul><li>Use factory objects: </li></ul><ul><ul><li>when system creates them automatically </li></ul></ul><ul><ul><li>when more than one class needs to have product specified </li></ul></ul><ul><ul><li>when most subclasses only specialize to override factory method </li></ul></ul>
    25. 25. FigureFactory new LineFigureFactory ElipseFigureFactory RectangleFigureFactory Figure LineFigure ElipseFigure RectangleFigure
    26. 26. Prototype <ul><li>Making a class hierarchy of factories seems wasteful. </li></ul><ul><li>The parameters of an object can be as important as its class. </li></ul><ul><li>Solution: </li></ul><ul><ul><li>Use any object as a factory by copying it to make a new instance. </li></ul></ul><ul><li>Advantages </li></ul><ul><ul><li>Don't need new factory hierarchy. </li></ul></ul><ul><ul><li>Can make new &quot;class&quot; by parameterizing an object </li></ul></ul><ul><li>Disadvantages </li></ul><ul><ul><li>Requires robust copying </li></ul></ul>
    27. 27. Making Prototype <ul><li>You have a design in which objects are parameterized by passing in classes. You are making new classes just for their constructors, or you want to make “composite classes”. </li></ul><ul><li>Make sure “copy” works. Define “new” as an instance method that returns a copy. Change client to pass in instances instead of classes. </li></ul>
    28. 28. Abstract Factory <ul><li>Sometimes a group of products are related -- if you change one, you might need to change them all. </li></ul><ul><li>Solution: </li></ul><ul><ul><li>Make a single object that can make any of the products. </li></ul></ul>ScrollBar MotifScrollBar PMScrollBar WidgitFactory CreateScrollBar CreateWindow MotifWidgetFactory CreateScrollBar CreateWindow PMWidgetFactory CreateScrollBar CreateWindow
    29. 29. Making Abstract Factory <ul><li>Give Producer a component called “Factory” </li></ul><ul><ul><li>Create class Factory </li></ul></ul><ul><ul><li>Add instance variable “factory” to Producer </li></ul></ul><ul><ul><li>Change constructor to have line factory:=Factory new </li></ul></ul><ul><li>Move factory methods to Factory </li></ul><ul><ul><li>Copy factory method to Factory </li></ul></ul><ul><ul><li>Change sends of createFoo to “factory createFoo” </li></ul></ul>
    30. 30. Builder <ul><li>Complex objects require a lot of work to make. </li></ul><ul><li>Solution: </li></ul><ul><ul><li>Factory must keep track of partly built product. </li></ul></ul><ul><ul><li>Client specifies product by performing series of operations on factory. </li></ul></ul>Client WindowBuilder AddScrollBar AddButton GetWindow
    31. 31. Implementing Builder <ul><li>Builder can make components using </li></ul><ul><ul><li>Factory Method </li></ul></ul><ul><ul><li>Abstract Factory, or </li></ul></ul><ul><ul><li>Prototype </li></ul></ul>WidgitFactory CreateScrollBar CreateWindow WindowBuilder AddScrollBar AddButton GetWindow PMWidgetFactory CreateScrollBar CreateWindow MotifWidgetFactory CreateScrollBar CreateWindow
    32. 32. Making Builder <ul><li>There are several places in your system where a complex object is built. These places need to mention a lot of classes, unless you use a pattern like Abstract Factory. </li></ul><ul><li>Constructors get complicated. Perhaps there are a lot of class methods that deal with construction. Construction needs temporary variables. </li></ul><ul><li>Make a class that builds the object for you. It hides the concrete classes that are used and temporary variables used during construction. </li></ul><ul><li>Result: Producers not coupled with Product. Builder is coupled with Product. </li></ul>
    33. 33. Summary of Factory Patterns <ul><li>Factory method -- use in simple cases so that you can change product </li></ul><ul><li>Abstract factory -- use when there is a set of related products </li></ul><ul><li>Builder -- use when product is complex </li></ul><ul><li>Prototype -- use when Factory Method is awkward and when classes are not objects, or when you want to specify new &quot;classes&quot; by composition </li></ul>
    34. 34. Singleton <ul><li>What if you want to make sure that a class has only one instance? </li></ul><ul><li>One possibility is global variables. Another is using class methods. </li></ul><ul><li>Best solution: store single instance in class variable. </li></ul>
    35. 35. Singleton <ul><li>The singleton class has a class variable “Instance” and a class method </li></ul><ul><li>instance </li></ul><ul><li>Instance isNil ifTrue: [Instance := super new]. </li></ul><ul><li>^Instance </li></ul><ul><li>Alternative: make “Instance” a class instance variable. </li></ul>
    36. 36. Managing dependences <ul><li>Cost of eliminating dependences </li></ul><ul><ul><li>More abstract </li></ul></ul><ul><ul><li>Harder to test </li></ul></ul><ul><ul><li>Harder to understand </li></ul></ul><ul><li>It is OK to depend on stable packages. </li></ul><ul><li>Stable = doesn’t change = has many dependents </li></ul>
    37. 37. Managing dependences Subsystem2 Application Library3 Library1 Library2 Subsystem1
    38. 38. Managing dependences Application2 Subsystem2 Subsystem1 Application1 Suppose Application2 depends on only a small part of Subsystem1, and that part doesn’t depend on Subsystem2
    39. 39. Managing dependences Application2 Subsystem2 Subsystem3 Application1 Subsystem1
    40. 40. Dependence management <ul><li>Determines </li></ul><ul><ul><li>Build times </li></ul></ul><ul><ul><li>Difficulty of testing </li></ul></ul><ul><ul><li>Frequency of rebuilding and retesting </li></ul></ul><ul><ul><li>Ease of reuse </li></ul></ul><ul><li>Design patterns help control dependences </li></ul>
    41. 41. Design patterns and refactoring <ul><li>Patterns are most useful for complex systems. </li></ul><ul><li>Add them later by refactoring </li></ul><ul><ul><li>Keep system simple – no unnecessary patterns </li></ul></ul><ul><ul><li>Keep system flexible – all needed patterns </li></ul></ul>
    42. 42. Next time <ul><li>More on Observer and creational patterns. </li></ul>