Download Object oriented programming and more Study notes Object Oriented Programming in PDF only on Docsity! © Kenneth M. Anderson, 2012 The Object-Oriented Paradigm CSCI 4448/5448: Object-Oriented Analysis & Design Lecture 2 — 08/30/2011 1 © Kenneth M. Anderson, 2012 Lecture Goals • Introduce the object-oriented paradigm • Contrast it with functional decomposition • Discuss important concepts of object-oriented programming • Discuss the difference between abstraction and encapsulation • This is VERY important • Address the problem of requirements and the need to deal with change 2 © Kenneth M. Anderson, 2012 Functional Decomposition • Decompose big problems into the functional steps required to solve it • For a very big problem, simply break it down to smaller problems • then decompose smaller problems into functional steps • Goal is to slice up the problems until they are at a level of granularity that is easy to solve in a couple of steps • Then arrange the steps into an order that solves all of the identified subproblems and, presto, the big problem is solved along the way • Extremely natural approach to problem solving; we do this almost without thinking about it 5 © Kenneth M. Anderson, 2012 Functional Decomposition: Problems • There are two main problems with this approach to design • It creates designs centered around a “main program” • This program is in control and knows all of the details about what needs to be done and all of the details about the program’s data structures • It creates designs that do not respond well to change requests • These programs are not well modularized and so a change request often requires modification of the main program; a minor change in a data structure, for example, might cause impacts throughout the entire main program 6 © Kenneth M. Anderson, 2012 With respect to change… • A process-based approach to solving problems does not lead to program structures that can gracefully react to change • And change in software development often involves a variation on an existing theme • display new types of shapes • change the way shapes are rendered • add new functionality to the program such as being able to move the shapes after they have been displayed • In “main programs,” these types of changes typically cause complexity to increase and require that lots of files have to be recompiled 7 © Kenneth M. Anderson, 2012 Start of a Journey (I) • What is the difference between abstraction and encapsulation? • Any takers? • How would you interpret the following statements if you heard them in casual (admittedly nerdy) conversation? • “That sound processing package offers a great set of abstractions!” • “Wow, that Employee class is horrible! There is no encapsulation!” 10 © Kenneth M. Anderson, 2012 Start of a Journey (II) • Identify which concept applies to the following statements • “I wonder if Java’s Map class will do what I need?” • “I wonder if I can prevent users of my library from finding out that MyClass.id is implemented as a floating point number?” • “I like how I can decide at run time whether my List variable will point at an instance of LinkedList or ArrayList! I mean List’s API is fine but it’s nice to know that I have the flexibility of picking the more efficient implementation when my list size is small” 11 © Kenneth M. Anderson, 2012 Start of a Journey (III) • Simple Definitions • Abstraction refers to the set of concepts that some entity provides you in order for you to achieve a task or solve a problem • Simple Example: the public methods of Java’s String class • Encapsulation refers to a set of language-level mechanisms or design techniques that hide implementation details of a class, module, or subsystem from other classes, modules, and subsystems • Simple Example: In most OO programming languages, marking an instance variable “private” ensures that other classes cannot access the value of that variable directly • They need to make use of a method in order to retrieve or update that particular internal variable 12 © Kenneth M. Anderson, 2012 Requirements • Requirements for a software system are initially generated during the analysis phase of software development and are, typically: • simple statements of desired functional capabilities • “the system should allow its users to sort records by priority” • statements of non-functional capabilities • “the system should support 10,000 simultaneous users” • statements of constraints that must be met • “the system will comply with regulation XYZ at all times” 15 © Kenneth M. Anderson, 2012 The Problem of Requirements (I) • The problem? Experienced developers will tell you that • Requirements are incomplete and do not tell the whole story • Requirements are typically wrong • factually wrong or become obsolete • Requirements and users are misleading • In addition, users may be non-technical and may not understand the range of options that could solve their problem • their ill informed suggestions may artificially constrain the space of solutions 16 © Kenneth M. Anderson, 2012 The Problem of Requirements (II) • The other problem with requirements is • “requirements always change” • They change because • a user’s needs change over time • as they learn more about a new problem domain, a developer’s ability to generate better solutions to the original problem (or the current problem if it has evolved) will increase • the system’s environment changes • new hardware, new external pressures, new techniques 17 © Kenneth M. Anderson, 2012 The Problem with Functional Decomposition • The book highlights a problem with code developed with functional decomposition • such code has weak cohesion and tight coupling • translation: “it does too many things and has too many dependencies” • Example • void process_records(records: record_list) { • // sort records, update values in records, print records, archive records and log each operation as it is performed … • } 20 © Kenneth M. Anderson, 2012 Cohesion • Cohesion refers to “how closely the operations in a routine are related” • A simplification is to say “we want this method to do just one thing” or “we want this module to deal with just one thing” • We want our code to exhibit strong cohesion (a.k.a. highly cohesive) • methods: the method performs one operation • classes: the class achieves a fine-grain design or implementation goal • packages: the package achieves a medium-grain design goal • subsystems: this subsystem achieves a coarse-grain design goal • system: the system achieves all design goals and meets its requirements 21 Code Complete by Steve McConnell; Microsoft Press, 1993 © Kenneth M. Anderson, 2012 Coupling • Coupling refers to “the strength of a connection between two routines” • It is a complement to cohesion • weak cohesion implies strong coupling • strong cohesion implies loose coupling • With strong or tight coupling, a single change in one method or data structure will cause ripple effects, that is, additional changes in other parts of the system • We want systems with parts that are highly cohesive and loosely coupled 22 Code Complete by Steve McConnell; Microsoft Press, 1993 © Kenneth M. Anderson, 2012 Transitioning to the OO Paradigm • The book asks • Would you do this in real life? • And the answer is (hopefully) NO! • What would you do instead? • You would assume that everyone has a conference program, knows where they need to be next, and will get their on their own • All you would do is end the session and head off to your next activity • At worst, you would have a list of the next sessions at the front of the class and you would tell everyone “use this info to locate your next session” 25 © Kenneth M. Anderson, 2012 Compare / Contrast • In the first scenario, • you know everything, you are responsible for everything, if something changes you would be responsible for handling it • you give very explicit instructions to each entity in the system • In the second scenario, • you expect the other entities to be self sufficient • you give very general instructions and • you expect the other entities to know how to apply those general instructions to their specific situation 26 © Kenneth M. Anderson, 2012 Benefits of the second scenario • The biggest benefit is that entities of the system have their own responsibilities • indeed this approach represents a shift of responsibility away from a central control program to the entities themselves • Suppose we had attendees and student volunteers in our session and that volunteers needed to do something special in between sessions • First approach: the session leader needs to know about the special case and remember to tell volunteers to do it before going to the next session • Second approach: the session leader tells each person “Go to your next session”; volunteers will then automatically handle the special case without the session leader needing to know anything about it • We can add new types of attendees without impacting the leader 27 © Kenneth M. Anderson, 2012 As an aside... • OO main programs tend to be short • On the order of create an object and send a message to it • See next slide… 30 © Kenneth M. Anderson, 2012 31 import wx1 2 from ACE.GUI.Managers.RepositoryManager import RepositoryManager3 4 class ACEApp(wx.App):5 6 def OnInit(self):7 8 bmp = wx.Image("images/ace_logo.png").ConvertToBitmap()9 wx.SplashScreen(bmp, wx.SPLASH_CENTRE_ON_SCREEN | wx.SPLASH_TIMEOUT, 500, None, -1)10 wx.SafeYield(None,True)11 self.repoman = RepositoryManager()12 return self.repoman.HandleAppStart(self)13 14 def OnExit(self):15 self.repoman.HandleAppQuit()16 17 if __name__ == '__main__':18 app = ACEApp(redirect=False)19 app.MainLoop()20 21 Create an object Send a message to it © Kenneth M. Anderson, 2012 iOS Main Program • Here’s the main program (roughly) of every iOS application in existence • It has roughly the same bootstrap code that we saw for the OS X application that we saw in Lecture 1 • The latest version of XCode generates slightly different code but the intent is still the same: bootstrap out of the procedural world and into OO 32 Page 1 of 1 main.m 8/25/11 8:38 AM #import <UIKit/UIKit.h> int main(int argc, char *argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; int retVal = UIApplicationMain(argc, argv, nil, nil); [pool release]; return retVal; } © Kenneth M. Anderson, 2012 Object Responsibilities • In OO Analysis and Design, it is best to think of an object as “something with responsibilities” • As you perform analysis (What’s the problem?), you discover responsibilities that the system must fulfill • You will eventually find “homes” for these responsibilities in the objects you design for the system; indeed this process can help you “discover” objects needed for the system • The problem domain will also provide many candidate objects to include in the system • This is an example of moving from a conceptual perspective to the specification and implementation perspectives • Our book delves further into these three types of perspectives 35 © Kenneth M. Anderson, 2012 Objects • Conceptual — a set of responsibilities • Specification — a set of methods • Implementation — a set of code and data • Unfortunately, OO A&D is often taught only at the implementation level • if previously you have used OO programming languages without doing analysis and design up front, then you’ve been operating only at the implementation level • as you will see, there are great benefits from starting with the other levels first 36 © Kenneth M. Anderson, 2012 Objects as Instances of a Class • If you have two Student objects, they each have their own data • e.g. Student A has a different set of values for its attributes than Student B • But they both have the same set of methods • This is true because methods are associated with a class that acts as a blueprint for creating new objects • We say “Objects are instances of a class” • Classes define the complete behavior of their associated objects • what data elements and methods they have and how these features are accessed (whether they are public or private) 37 © Kenneth M. Anderson, 2012 Classes (III) • Inheritance relationships are known as is-a relationships • Undergraduate IS-A Student • This phrase is meant to reinforce the concept that the subclass represents a more refined, more specific version of the superclass • If need be, we can treat the subclass as if it IS the superclass. • It has all the same attributes and all the same methods as the superclass • so code that was built to process the superclass can equally apply to the subclass 40 © Kenneth M. Anderson, 2012 Classes (IV) • Classes can control the accessibility of the features of their objects • That is they can typically specify whether an attribute or method has an accessibility of public, protected, or private. • This ability to hide features of a class/module is referred to as encapsulation or information hiding; • however, encapsulation is a topic that is broader than just data hiding, as we will discuss later in the semester 41 © Kenneth M. Anderson, 2012 Accessibility, continued • Assume • Object A is an instance of class X • Object B is an instance of class Y which is a subclass of X; • Object C is an instance of class Z which is unrelated to X and Y • See next slide 42 © Kenneth M. Anderson, 2012 Accessibility: Quick Example • The example code for this lecture has a simple Java program • Classes X, Y, & Z, split between two packages foo and bar • Test program instantiates A, B, and C and then has them call each other in various ways • Note: I had to split X and Y across two packages because the “protected” modifier only follows the general definition on the previous slide when classes are in different packages • In Java, the protected modifier acts like “public” for classes in the same package (!!!) 45 © Kenneth M. Anderson, 2012 Classes (V) • Classes can control how their objects are created and destroyed • OO Programming languages will (typically) provide “special methods” known as constructors and destructors (a.k.a. finalizers) to handle these two phases in an object’s life cycle • Constructors are useful for ensuring that an object is properly initialized before any other object makes use of it • Destructors are useful for ensuring that an object has released all of the resources it consumed while it was active • Destructors can be tricky; in languages with garbage collection, an inactive object might hang around for a significant amount of time before the garbage collector gets around to reclaiming its space 46 © Kenneth M. Anderson, 2012 One benefit of superclasses • Treat all instances of a superclass-subclass hierarchy as if they were all instances of the superclass even if some are instances of subclasses • Example • Suppose we have the classes, Undergraduate, MastersStudent and PhDStudent in a software system • Problem: We may have a need for acting on all instances of these three classes at once, for instance, storing them all in a collection, sorting by last name and displaying a roster of the entire university • Solution: Make all three of these classes a subclass of the class Student; You can then add all of the students to a single collection and treat them all the same 47 © Kenneth M. Anderson, 2012 50 import java.util.LinkedList;1 import java.util.List;2 3 public class Test {4 5 public static void main(String[] args) {6 7 List<Student> students = new LinkedList<Student>();8 9 students.add(new Undergraduate("Bilbo Baggins"));10 students.add(new MastersStudent("Aargorn"));11 students.add(new PhDStudent("Gandalf the White"));12 13 for (Student s: students) {14 System.out.println("" + s);15 }16 17 System.out.println();18 19 for (Student s: students) {20 s.saySomething();21 }22 23 }24 25 }26 27 © Kenneth M. Anderson, 2012 51 The True Power: Clean Code! • The most powerful code in the previous example was • Why? • You can add as many subclasses to the Student hierarchy as you want and this code never has to change! • It doesn’t even have to be recompiled (demo) • Indeed, given the right techniques, a server running this code doesn’t even need to be “brought down”; the new subclass can be dynamically loaded and this code will recognize instances of that subclass and do the right thing for (Student s: students) { s.saySomething(); } © Kenneth M. Anderson, 2012 Not just Java • The benefits of polymorphism can be realized in any OO language • Here’s a quick demo of the same example in Objective-C 52 © Kenneth M. Anderson, 2012 Abstract Classes • The classes that sit at the top of an object hierarchy are typically abstract classes while the classes that sit near the bottom of the hierarchy are called concrete classes • Abstract classes • define a set of generic behaviors for a related set of subclasses; • act as placeholders for other classes defining method signatures that they must implement, defining method bodies for behaviors that should be the same across all subclasses, defining data that will be useful for all subclasses • In OO programming languages, abstract classes cannot be instantiated • instead you instantiate concrete classes but access them via the interface defined by the abstract class 55 © Kenneth M. Anderson, 2012 Summary • In this lecture, we have touched on a variety of OO concepts • Functional Decomposition vs. the OO Paradigm • Requirements and Change in Software Development • Objects, Classes (Abstract and Concrete) • Polymorphism and Encapsulation 56 © Kenneth M. Anderson, 2012 Coming Up Next • Homework 1: To be assigned today • Lecture 3: UML • Read Chapter 2 of the Textbook • Lecture 4: More review of fundamental OO A&D concepts 57