L04 Software Design 2

  • 164 views
Uploaded on

Framhald af umfjöllun um hlutbundna forritun og hönnun. Nú förum við yfir Generic Programming sem sem leið til að búa til sveigjanlega og endurnýtanlegar einingar. Skoðum líka reflection. Þá verður …

Framhald af umfjöllun um hlutbundna forritun og hönnun. Nú förum við yfir Generic Programming sem sem leið til að búa til sveigjanlega og endurnýtanlegar einingar. Skoðum líka reflection. Þá verður farið fyrir hvernig má hann laustengdar einingar og notum við frægan andarleik sem dæmi.

Þá mun Code Horror Dude kíkja í heimsókn

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
164
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
22
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Lecture 04 Software Design 2
  • 2. Agenda  Programming with Objects – Classes – Interfaces – Generic programming – Reflection  Software Design – Ducks…
  • 3. Reading  Barbin Introduction, 1 Core Principles – Separation of concerns (SoC) – Coupling – Cohesion – Information Hiding  Don’t Repeat Yourself  Polymorphism  Optional: – http://docs.oracle.com/javase/tutorial/
  • 4. Generic Programming
  • 5. Generic Programming  Programming in an data type independent way – Same code is used regardless of the data type  Example – Sort can be applied to any data type – Generic collection • Java Collection Framework  Design Principle – Always use the most generic data type possible
  • 6. Generic Programming  All classes extend Object – Allows generic algorithms and data structures static int find (Object[] a, Object key) { int i; for (i=0;i<a.length;i++) if (a[i].equals(key)) return i; return -1; } Employee[] staff = new Employee[10]; Employee e1 = new Employee("Dilbert"); staff[x] = e1; int n = find(staff, e1);
  • 7. Generic Programming  Generic collections – ArrayList is an example class that uses Object ArrayList al = new ArrayList(); al.add (new Employee ("Dilbert")); al.add (new Employee ("Wally")); al.add (new Employee ("Alice")); Iterator i = al.iterator(); Employee e; while (i.hasNext()) { e = (Employee)i.next(); System.out.println(e.getName()); } Dilbert Wally Alice
  • 8. Generic Programming  Generic collections – The Collections class is another example List<Employee> list = new ArrayList<Employee>(); list.add (new Employee ("Dilbert")); list.add (new Employee ("Wally")); list.add (new Employee ("Alice")); Collections.sort(list); for (Employee e: list) { System.out.println(e); } Alice Dilbert Wally
  • 9. Reflection
  • 10. Reflection  Reflection allows examination and manipulation of objects at runtime – Get information about a class • Fields, methods, constructors, and super classes • Constants and method declarations belong to an interface – Create an instance of a class whose name is not known until runtime – Get and set the value of an object's field, even if the field name is unknown to your program until runtime – Invoke a method on an object, even if the method is not known until runtime
  • 11. Reflection static void showMethods(Object o) { Class c = o.getClass(); Method[] theMethods = c.getMethods(); for (int i = 0; i < theMethods.length; i++) { String methodString = theMethods[i].getName(); System.out.println("Name: " + methodString); String returnString = theMethods[i].getReturnType().getName(); System.out.println(" Return Type: " + returnString); Class[] parameterTypes = theMethods[i].getParameterTypes(); System.out.print(" Parameter Types:"); for (int k = 0; k < parameterTypes.length; k ++) { String parameterString = parameterTypes[k].getName(); System.out.print(" " + parameterString); } System.out.println(); } } }
  • 12. Reflection public class ReflectMethods { public static void main(String[] args) { Polygon p = new Polygon(); showMethods(p); } Name: getBoundingBox Bla Return Type: java.awt.Rectangle Parameter Types: Name: contains Return Type: boolean Parameter Types: java.awt.geom.Point2D ... Name: toString Return Type: java.lang.String Parameter Types:
  • 13. Reflection  Reflection is very useful in frameworks – Infrastructure code – “plumbing” – The “Noise”  Examples – Create Java objects from XML descriptions – Load classes at runtime and invoke methods – Tools and utilities for development
  • 14. Dynamically Loading Classes  Classes can be dynamically loaded at runtime – Offers the flexibility to decide which class to run dynamically – Class names can be specified in configuration files  Class class Class instanceClass = Class.forName("RssFeedReader"); reader = (FeedReader)instanceClass.newInstance();
  • 15. A) BD B) DB C) BDC D) Compilation fails QUIZ class Top { public Top(String s) { System.out.print("B"); } } public class Bottom2 extends Top { public Bottom2(String s) { System.out.print("D"); } public static void main(String [] args) { new Bottom2("C"); System.out.println(" "); } }
  • 16. A) BD B) DB C) BDC D) Compilation fails QUIZ ✔ class Top { public Top(String s) { System.out.print("B"); } } public class Bottom2 extends Top { public Bottom2(String s) { System.out.print("D"); } public static void main(String [] args) { new Bottom2("C"); System.out.println(" "); } }
  • 17. Software Design
  • 18. Object Oriented Design  Design and implementation of software needs to be of quality – Badly designed, well implemented = problem! – Well designed, badly implemented = problem! CODE HORROR!! CODE HORROR DUDE
  • 19. Object Oriented Design  Good design Is based on OO principles Abstracts complex APIs such as J2EE Is flexible and can be changed Contains loosely coupled components
  • 20.  Example from Head First Design Patterns
  • 21. Getting Started  SimUDuck is highly successful duck pond simulation game  Original design
  • 22. Change Request  But now we need the ducks to FLY
  • 23. Problem!  But not all duck fly – We forgot Rubber Duck!
  • 24. How can we fix this?  Just override fly and quack to do nothing
  • 25. We even think ahead  We fix all non-flyable and non-quackable ducks as well Code smell!
  • 26. QUIZ Which of the following are disadvantages of using inheritance to provide Duck behavior? A) Code is duplicated across subclasses B) Runtime behavior changes are difficult C) We can’t make ducks dance D) Hard to gain knowledge of all duck behaviors E) Ducks can’t fly and quack at the same time F) Changes can unitentionally affect other ducks ✔ ✔ ✔ ✔
  • 27. The Problem  The problem is this – Derived classes (RubberDuck) are forced to inherit behaviour they don’t have – Derived classes (RubberDuck) needs to be exposed to the inner workings of the superclass (Duck) – Users of the base class (Duck) should expect same functionality – Violation of the Liskov Substitution Principle
  • 28. The Liskov Substitution Principle Subtypes must be substitutable for their base types. Code that uses references to base class must be able to use objects of derived classes without knowing it. Barbara Liskov
  • 29. The Liskov Substitution Principle  All code operating with reference to the base class should be completely transparent to the type of the inherited object  It should be possible to substitute an object of one type with another within the same class hierarchy  Inheriting classes should not perform any actions that will invalidate the assumptions made by the base class
  • 30. LSP Example public class Rectangle { protected int _width; protected int _height; public int getWidth() { return _width; } public int getHeight() { return _height; } public void setWidth(int width) { _width = width; } public void setHeight(int height) { _height = height; } }
  • 31. LSP Example public class Square extends Rectangle { public void setWidth(int width) { _width = width; _height = width; } public void setHeight(int height) { _height = height; _width = _height; } } Implementation convenience
  • 32. LSP Example import junit.framework.Assert; import org.junit.Test; public class RectangleTests { @Test public void areaOfRectangle() { Rectangle r = new Square(); r.setWidth(5); r.setHeight(2); // Will Fail - r is a square and sets // width and height equal to each other. Assert.assertEquals(r.getWidth() * r.getHeight(),10); } }
  • 33. Trying to fix the Problem  Let’s try using interfaces – Flyable and Quackable Code duplication!
  • 34. What is the Problem?  We tried this – Inheritance changes all subcasses – Interfaces cause code duplication  The problem is we are mixing different types of code in one type of classes  Fix – Separate Variation Design Principle – Take what varies and encapsulate it so it wont affect the rest of the code
  • 35. Separate Variations Identify the aspects of your application that vary and separate them from what stays the same
  • 36. Separation of Concerns  Separate what changes from what stays the same – Move duck behavior to a separte classes FlyWithWings flyBehavior = new FlyWithWings(); DATA TYPE IS TOO SPECIFIC
  • 37. Separation of Concerns  But the Duck classes cannot use the concrete behavior classes! – We need an interface or supertype FlyBehavior flyBehavior = new FlyWithWings(); INTERFACE - POLYMORPHISIM
  • 38. The Interface Design Principle Program to an interface, not an implementation
  • 39. Loose Coupling with Interfaces  Advantages – The ability to change the implementing class of any application object without affecting calling code – Total freedom in implementing interfaces – The ability to provide simple test implementations and stub implementations of application interfaces as necessary
  • 40. Program to an interfaces  Program to an implementation Dog d = new Dog(); d.bark();  Program to interface/subtype Animal animal = new Dog(); animal.makeSound();  Program to unknown creation Animal animal = getAnimal(); animal.makeSound();
  • 41. Program to an interfaces  Dependency Injection – Make the caller responsible for setting the dependency private Animal animal; public setAnimal(Animal animal) { this.animal = animal; } ... animal.makeSound(); Injection happens here, in the set-method LOOSE COUPLING = BEAUTIFUL!
  • 42. Implementing Behavior  We can add new behaviors without touching the Duck classes
  • 43. Integrating the Behavior  The Duck classes will now delegate its flying and quacking behavior Behavior interfaces Perform the Bahavior
  • 44. Integrating the Behavior  Using the behavior public class Duck { QuackBehavior quackBehavior; ... public void performQuack() { quackBehavior.performQuack() } } We don’t care what kind of object this is, all we care is that it knows how to quack!
  • 45. Integrating the Behavior  Setting the behavior public class MallardDuck extends Duck { public MallardDuck() { quackBehavior = new Quack(); flyBehavior = new FlyWithWings(); } } This is not programming to an interface!
  • 46. Setting Behavior Dynamically  Add two new methods to the Duck class  Dependency Injection public void setFlyBehavior(FlyBehavior flyBehavior) { this.flyBehavior = flyBehavior } public void setQuackBehavior(QuackBehavior quackBehavior) { this.quackBehavior = quackBehavior } DuckFactory { public Duck getMallardDuck() { Duck duck = new MallardDuck() duck.setFlyBehavior(new FlyWithWings()); duck.setQuackBehavior(new Quack()); return duck; } }
  • 47. Setting Behavior Dynamically  The idea – Don´t think: Mallard is-a flying duck, think: it has-a flying behavior – Putting two classes together where one is a member in the other is a composition  Creating systems using composition give flexibilty – You can change the behavior at runtime
  • 48. Composition Design Principle Favor composition over inheritance
  • 49. Object Composition  Problems with concrete inheritance – Class hierarchy can get rigid – Difficult to change the implementation  Object Composition is more flexible – Allows the behaviour of an object to be altered at run time, through delegating part of its behaviour to an interface and allowing callers to set the implementation of that interface
  • 50. Summary  OO Programming is powerful – If used correctly – Remember Encapsulation, Interfaces, Polymorphism  Generic programming – Using classes, abstract classes and interfaces can lead to powerful and flexible programs  Reflection – Powerful for building infrastructure
  • 51. EXERCISE Job interview question You are given the assignment of creating a component that needs to know sales statistics of Lottery tickets. You know that there is a another component in the system, Sale Server, that handles the sale. You need real-time information. What would you suggest?
  • 52. Design Patterns  Design pattern is a general solution to a common problem in software design – Systematic approach for problems that reoccur in software development – Not complete solution but starting point for design – Not code ready to use – Patterns have names and definitions – Built on common practices  Patterns should not be language dependant – However patterns apply for types of programming languages
  • 53. Next  Design Patterns