Full Transcript

Object Oriented Analysis and Design Presented By Ranumayee Sing Asst. Prof. PMEC, BAM The Object Model Object-oriented technology is built on a sound engineering foundation, whose elements we collectively call the object model of devel...

Object Oriented Analysis and Design Presented By Ranumayee Sing Asst. Prof. PMEC, BAM The Object Model Object-oriented technology is built on a sound engineering foundation, whose elements we collectively call the object model of development or simply the object model. The object model encompasses the principles of abstraction, encapsulation, modularity, hierarchy, typing, concurrency, and persistence. The object-oriented analysis and design is fundamentally different than traditional structured design approaches: It requires a different way of thinking about decomposition, and it produces software architectures that are largely outside the realm of the structured design culture. The Evolution of the Object Model Object-oriented development did not spontaneously generate itself from the ashes of the uncounted failed software projects that used earlier technologies. It is not a radical departure from earlier approaches. Indeed, it is founded in the best ideas from prior technologies. The two sweeping trends of Software Engineering history: 1. The shift in focus from programming-in-the-small to programming-in-the-large 2. The evolution of high-order programming languages The Generations of Programming Languages Wegner has classified some of the more popular high-order programming languages in generations arranged according to the language features they first introduced First-generation languages (1954–1958) FORTRAN I Mathematical expressions ALGOL 58 Mathematical expressions Flowmatic Mathematical expressions IPL V Mathematical expressions Second-generation languages (1959–1961) FORTRAN II Subroutines, separate compilation ALGOL 60 Block structure, data types COBOL Data description, file handling Lisp List processing, pointers, garbage collection Third-generation languages (1962–1970) PL/1 FORTRAN + ALGOL + COBOL ALGOL 68 Rigorous successor to ALGOL 60 Pascal Simple successor to ALGOL 60 Simula Classes, data abstraction The generation gap (1970–1980) Many different languages were invented, but few endured. However, the following are worth noting: C Efficient; small executables FORTRAN 77 ANSI standardization Let’s expand on Wegner’s categories. Object-orientation boom (1980–1990, but few languages survive) Smalltalk 80 Pure object-oriented language C++ Derived from C and Simula Ada83 Strong typing; heavy Pascal influence Eiffel Derived from Ada and Simula Emergence of frameworks (1990–today) Visual Basic Eased development of the graphical user interface (GUI) for Windows applications Java Successor to Oak; designed for portability Python Object-oriented scripting language J2EE Java-based framework for enterprise computing.NET Microsoft’s object-based framework Visual C# Java competitor for the Microsoft.NET Framework Visual Basic.NET Visual Basic for the Microsoft.NET Framework First-generation languages were used primarily for scientific and engineering applications, and the vocabulary of this problem domain was almost entirely mathematics. This first generation of high-order programming languages therefore represented a step closer to the problem space and a step further away from the underlying machine. Among second-generation languages, the emphasis was on algorithmic abstractions. Again, this new generation of high-order programming languages moved us a step closer to the problem space and further away from the underlying machine. Third generation languages such as ALGOL 60 and, later, Pascal evolved with support for data abstraction. Now a programmer could describe the meaning of related kinds of data (their type) and let the programming language enforce these design decisions. This generation of high-order programming languages again moved our software a step closer to the problem domain and further away from the underlying machine. The number of object-based and object-oriented languages are boomed in 1980s and early 1990s. Since 1990 the mainstream OO languages (JAVA, C++) and frameworks (J2EE,.NET) provides support to programmers by offering components and services. The Topology of First- and Early Second- Generation Programming Languages By topology, we mean the basic physical building blocks of the language and how those parts can be connected. For languages such as FORTRAN and COBOL, the basic physical building block of all applications is the subprogram (or the paragraph, for COBOL). Applications written in these languages exhibit a relatively flat physical structure, consisting only of global data and subprograms. The arrows in figure indicate dependencies of the subprograms on various data. An error in one part of a program can have a devastating ripple effect across the rest of the system because the global data structures are exposed for all subprograms to see. Fig: The Topology of First- and Early Second-Generation Programming Languages The Topology of Late Second- and Early Third-Generation Programming Languages By the mid-1960s, programs were finally being recognized as important intermediate points between the problem and the computer. The first software abstraction, now called the ‘procedural’ abstraction Subprograms could serve as an abstraction mechanism had three important consequences. First, languages were invented that supported a variety of parameter-passing mechanisms Second, the foundations of structured programming were laid, manifesting themselves in language support for the nesting of subprograms and the development of theories regarding control structures and the scope and visibility of declarations Third, structured design methods emerged, offering guidance to designers trying to build large systems using subprograms as basic physical building blocks. This topology addresses some of the inadequacies of earlier languages, namely, the need to have greater control over algorithmic abstractions, but it still fails to address the problems of programming-in-the-large and data design. Fig: The Topology of Late Second- and Early Third-Generation Programming Languages The Topology of Late Third-Generation Programming Languages Larger programming projects meant larger development teams, and thus the need to develop different parts of the same program independently. The answer to this need was the separately compiled module, which in its early conception was little more than an arbitrary container for data and subprograms. Modules were simply to group subprograms that were most likely to change together. Modular structure had few rules that required semantic consistency among module interfaces. Most of these languages had dismal support for data abstraction and strong typing, the errors could be detected only during execution of the program Fig: The Topology of Late Third-Generation Programming Languages The Topology of Object-Based and Object- Oriented Programming Languages Data abstraction is important to mastering complexity. The abstraction first appeared in the language Simula and was improved upon, resulting in the development of several languages such as Smalltalk, Object Pascal, C++, Ada, Eiffel, and Java. These languages are called object-based or object-oriented. The physical building block in such languages is the module, which represents a logical collection of classes and objects instead of subprograms. To state it another way, “If procedures and functions are verbs and pieces of data are nouns, a procedure-oriented program is organized around verbs while an object-oriented program is organized around nouns” For this reason, the physical structure of a small to moderate-sized object-oriented application appears as a graph, not as a tree Additionally, there is little or no global data. Data and operations are united in such a way that the fundamental logical building blocks of our systems are no longer algorithms, but instead are classes and objects. Fig: The Topology of Small to Moderate-Sized Applications Using Object-Based and Object-Oriented Programming Languages Programming-in-the-colossal: In large systems, clusters of abstractions built in layers on top of one another. At any given level of abstraction, find meaningful collections of objects that collaborate to achieve some higher-level behavior. If we look inside any given cluster to view its implementation, we unveil yet another set of cooperative abstractions. Fig: The Topology of Large Applications Using Object-Based and Object-Oriented Programming Languages Foundations of the Object Model Structured design methods evolved to guide developers who were trying to build complex systems using algorithms as their fundamental building blocks. Similarly, object-oriented design methods have evolved to help developers exploit the expressive power of object-based and object-oriented programming languages, using the class and object as basic building blocks. Foundations—The Object Model Is the unifying concept in Computer Science, applicable not just to programming languages but also to the design of user interfaces, databases, and even computer architectures Thus Object-oriented analysis and design represents an evolutionary development, not a revolutionary one The object model derives from so many disparate sources which has muddle of terminology. Ex- A Smalltalk programmer uses methods A C++ programmer uses virtual member functions A CLOS programmer uses generic functions An Object Pascal programmer talks of a type coercion An Ada programmer calls the same thing a type conversion A C# or Java programmer would use a cast The concept of object is central to object-oriented Stefik and Bobrow define objects as “entities that combine the properties of procedures and data since they perform computations and save local state”. Jones further clarifies this term by noting that “in the object model, emphasis is placed on crisply characterizing the components of the physical or abstract system to be modeled by a programmed system”. Objects have a certain ‘integrity’ which cannot violated. An object can only change state, behave, be manipulated, or stand in relation to other objects in ways appropriate to that object. Foundations—The Object Model As Yonezawa and Tokoro point out, “The term ‘object’ emerged almost independently in various fields in computer science, almost simultaneously in the early 1970s, to refer to notions that were different in their appearance, yet mutually related. All of these notions were invented to manage the complexity of software systems in such a way that objects represented components of a modularly decomposed system or modular units of knowledge representation” Levy adds that the following events have contributed to the evolution of object-oriented concepts: Advances in computer architecture, including capability systems and hardware support for operating systems concepts Advances in programming languages, as demonstrated in Simula, Smalltalk, CLU, and Ada Advances in programming methodology, including modularization and information hiding Three more contributions to the foundation of the object model: Advances in database models Research in artificial intelligence Advances in philosophy and cognitive science The concept of object begins in hardware with invention of descriptor-based architecture to capability-based architectures Computers can also have an object-oriented architecture with advantages: better error detection, improved execution efficiency, fewer instruction types, simpler compilation, and reduced storage requirements. Object-oriented architectures are used object-oriented operating systems. Dijkstra’s work with the THE multiprogramming system first introduced the concept of building systems as layered state machines Other object-oriented operating systems include the Plessey/System 250 (for the Plessey 250 multiprocessor), Hydra (for CMU’s C.mmp), CALTSS (for the CDC 6400), CAP (for the Cambridge CAP computer), UCLA Secure UNIX (for the PDP 11/45 and 11/70), StarOS (for CMU’s Cm*), Medusa (also for CMU’s Cm*), and iMAX (for the Intel 432). The fundamental ideas of classes and objects first appeared in the language Simula 67. Smalltalk-80, took Simula’s object-oriented paradigm, an instance of class. In the 1970s languages such as Alphard, CLU, Euclid, Gypsy, Mesa, and Modula were developed, which supported the emerging ideas of data abstraction. The unification of object-oriented concepts with C has lead to the languages C++ and Objective C. Java avoid common programming errors when using C++. Adding object-oriented programming mechanisms to Pascal has led to the languages Object Pascal, Eiffel, and Ada. Lisp incorporate the object-oriented features of Simula and Smalltalk Dijkstra first identified the importance of composing systems in layers of abstraction Parnas later introduced the idea of information hiding In the 1970s a number of researchers, most notably Liskov and Zilles , Guttag, and Shaw, pioneered the development of abstract data type mechanisms. Hoare contributed to these developments with his proposal for a theory of types and subclasses. Database technology contribute ideas of the entity-relationship (ER) approach to data modeling. The ER model, first proposed by Chen. In the field of artificial intelligence, developments in knowledge representation have contributed to an understanding of object-oriented abstractions. In 1975, Minsky first proposed a theory of frames to represent real-world objects by image and natural language recognition systems. Lastly, philosophy and cognitive science have contributed to the advancement of the object model. In the twentieth century, Rand expanded on these themes in her philosophy of objectivist epistemology. Minsky has proposed a model of human intelligence in which he considers the mind to be organized as a society of otherwise mindless agents. Object-Oriented Programming Defined it as follows: Object-oriented programming is a method of implementation in which programs are organized as cooperative collections of objects, each of which represents an instance of some class, and whose classes are all members of a hierarchy of classes united via inheritance relationships. Three important parts to this definition: 1. Object-oriented programming uses objects, not algorithms, as its fundamental logical building 2. Each object is an instance of some class 3. Classes may be related to one another via inheritance relationships A language is object-oriented if and only if it satisfies the following requirements: It supports objects that are data abstractions with an interface of named operations and a hidden local state. Objects have an associated type [class]. Types [classes] may inherit attributes from supertypes [superclasses]. If a language does not provide direct support for inheritance, then it is not object-oriented. Cardelli and Wegner distinguish such languages by calling them object-based rather than object-oriented. Under this definition, Smalltalk, Object Pascal, C++, Eiffel, CLOS, C#, and Java are all object-oriented, and Ada83 is object-based (support for object orientation was later added to Ada95). Object-Oriented Design Object-oriented design is a method of design encompassing the process of object-oriented decomposition and a notation for depicting both logical and physical as well as static and dynamic models of the system under design. There are two important parts to this definition: object-oriented design 1. Leads to an object-oriented decomposition 2. Uses different notations to express different models of the logical (class and object structure) and physical (module and process architecture) design of a system, in addition to the static and dynamic aspects of the system. Object-Oriented Analysis Object-oriented analysis (OOA) emphasizes the building of real-world models, using an object-oriented view of the world: Object-oriented analysis is a method of analysis that examines requirements from the perspective of the classes and objects found in the vocabulary of the problem domain. How are OOA, OOD, and OOP related? The products of object-oriented analysis serve as the models from which an object-oriented design is started; the products of object-oriented design can then be used as blueprints for completely implementing a system using object-oriented programming methods. Elements of the Object Model Jenkins and Glasgow observe that “most programmers work in one language and use only one programming style”. Bobrow and Stefik define a programming style as “a way of organizing programs on the basis of some conceptual model of programming and an appropriate language to make programs written in the style clear” Five main kinds of programming styles 1. Procedure-oriented Algorithms 2. Object-oriented Classes and objects 3. Logic-oriented Goals, often expressed in a predicate calculus 4. Rule-oriented If–then rules 5. Constraint-oriented Invariant relationships Example- Rule-oriented programming is best suited for knowledge base Procedure-oriented programming is best suited for design of computation-intense operations Object-oriented style is best suited for the broadest set of applications, serve as architectural framework for other paradigms For all things object-oriented, the conceptual framework is the object model. There are four major elements of this model: 1. Abstraction 2. Encapsulation 3. Modularity 4. Hierarchy By major, a model without any one of these elements is not object-oriented. There are three minor elements of the object model: 1. Typing 2. Concurrency 3. Persistence By minor, each of these elements is a useful, but not essential, part of the object model. Without this conceptual framework, using Smalltalk, Object Pascal, C++, Eiffel, or Ada languages, programming can possible but consider as FORTRAN, Pascal, or C application The Meaning of Abstraction Combining the different viewpoints, an abstraction can be defined as follows: An abstraction denotes the essential characteristics of an object that distinguish it from all other kinds of objects and thus provide crisply defined conceptual boundaries, relative to the perspective of the viewer. An abstraction focuses on the outside view of an object and so serves to separate an object’s essential behavior from its implementation. The abstraction barrier can be achieved by Principle of least commitment, through which the interface of an object provides its essential behavior Principle of least astonishment is the additional principle, through which an abstraction captures the entire behavior of some object “There is a spectrum of abstraction, from objects which closely model problem domain entities to objects which really have no reason for existence”. These kinds of abstractions include the following: Entity abstraction An object that represents a useful model of a problem domain or solution domain entity Action abstraction An object that provides a generalized set of operations, all of which perform the same kind of function Virtual machine abstraction An object that groups operations that are all used by some superior level of control, or operations that all use some junior-level set of operations Coincidental abstraction An object that packages a set of operations that have no relation to each other Individually, each operation that contributes to this contract has a unique signature comprising all of its formal arguments and return type. The entire set of operations that perform on an object, together with legal ordering in which they may be invoked, called protocol. A protocol denotes the ways in which an object may act and react and thus constitutes the entire static and dynamic outside view of the abstraction. The idea of an abstraction is the concept of invariance. An invariant is some Boolean (true or false) condition whose truth must be preserved For each operation associated with an object, define preconditions (invariants assumed by the operation) and postconditions (invariants satisfied by the operation) If a precondition is violated, this means that a client has not satisfied its part of the bargain, and hence the server cannot proceed reliably If a postcondition is violated, this means that a server has not carried out its part of the contract, and so its clients can no longer trust the behavior of the server. All abstractions have static as well as dynamic properties. For example, a file object takes up a certain amount of space on a particular memory device; it has a name, and it has contents. These are all static properties. The value of each of these properties is dynamic, relative to the lifetime of the object: A file object may grow or shrink in size, its name may change, its contents may change. In procedure-oriented style of programming, the activity that changes the dynamic value of objects is the central part of all programs; things happen when subprograms are called and statements are executed. In a rule-oriented style of programming, things happen when new events cause rules to fire, which in turn may trigger other rules, and so on. In an object-oriented style of programming, things happen whenever we operate on an object (i.e., when we send a message to an object). Thus, invoking an operation on an object elicits some reaction from the object. Examples of Abstraction A hydroponics farm Sensors for air and water temperature, humidity, light, pH, and nutrient concentrations, among other things Viewed from the outside, a temperature sensor is simply an object that knows how to measure the temperature at some specific location A sensor is responsible for knowing the temperature at a given location and reporting that temperature when asked The abstraction is passive The sensor is active by sending temperature when there is a change of temperature to a certain degrees from given setpoint. Let’s consider a different abstraction. For each crop, there must be a growing plan that describes how temperature, light, nutrients, and other conditions should change over time to maximize the harvest. No object stands alone; every object collaborates with other objects to achieve some behavior. Our design decisions about how these objects cooperate with one another define the boundaries of each abstraction and thus the responsibilities and protocol of each object. The Meaning of Encapsulation Abstraction and encapsulation are complementary concepts: Abstraction focuses on the observable behavior of an object, whereas encapsulation focuses on the implementation that gives rise to this behavior Encapsulation hides all the secrets of an object, the structure as well as the implementation of its methods are hidden Ex- In plant, photosynthesis ignores the plant root and chemistry of cell wall. Database depends on schema and ignores the physical storage “For abstraction to work, implementations must be encapsulated”. Each class must have two parts: an interface and an implementation. The interface of a class captures only its outside view, and abstraction of the behavior common to all instances of the class. The interface of a class is the one place where all of the assumptions are present for any instances of the class The implementation of a class comprises the representation of the abstraction as well as the mechanisms that achieve the desired behavior. The implementation encapsulates details about which no client may make assumptions. To summarize, encapsulation is defined as follows: Encapsulation is the process of compartmentalizing the elements of an abstraction that constitute its structure and behavior; encapsulation serves to separate the contractual interface of an abstraction and its implementation. Britton and Parnas call these encapsulated elements the “secrets” of an abstraction Examples of Encapsulation In Hydroponics Gardening System A heater- operations are turn it on, turn it off and find out if it is running Another object i.e. Heater Controller collaborate with a temperature sensor and a heater to achieve higher-level behavior Builds on the primitive semantics of temperature sensors and heaters and adds some new semantics, namely, hysteresis, which prevents the heater from being turned on and off too rapidly when the temperature is near boundary conditions. Implementation encapsulates two secrets: the use of an open hash table and the use of extrapolation to reduce our storage requirements Hiding is a relative concept: What is hidden at one level of abstraction may represent the outside view at another level of abstraction. “Hiding is for the prevention of accidents, not the prevention of fraud” No programming language prevents a human from literally seeing the implementation of a class, but an operating system might deny access to a particular file that contains the implementation of a class The Meaning of Modularity “The act of partitioning a program into individual components can reduce its complexity to some degree Partitioning a program is that it creates a number of well-defined, documented boundaries within the program. In Smalltalk, there is no concept of a module, so the class forms the only physical unit of decomposition Java has packages that contain classes In many other languages, including Object Pascal, C++, and Ada, the module is a separate language construct and therefore warrants a separate set of design decisions. In these languages, classes and objects form the logical structure of a system; we place these abstractions in modules to produce the system’s physical architecture For larger applications with many hundreds of classes, the use of module is essential to help manage the complexity Modularization consists of dividing a program into modules which can be compiled separately, but which have connections with other modules The connections between modules are the assumptions which the modules make about each other Deciding on the right set of modules for a given problem is almost as hard a problem as deciding on the right set of abstractions Because the solution may not be known when the design stage starts, decomposition into smaller modules may be quite difficult The older application such as compiler writing, this process may become standard, but for new ones such as defence systems or spacecraft control, it may be quite difficult For tiny problems, every class and object in same package. In trivial software, group logically related classes and objects in the same module and expose only those elements that other modules absolutely must see In traditional structured design, modularization is primarily concerned with the meaningful grouping of subprograms, using the criteria of coupling and cohesion In object-oriented design, the task is to decide where to physically package the classes and objects, which are distinctly different from subprograms. Technical or nontechnical guideline to achieve an intelligent modularization of classes and objects The overall goal of the decomposition into modules is the reduction of software cost by allowing modules to be designed and revised independently Each module’s structure should be simple enough that it can be understood fully; it should be possible to change the implementation of other modules without knowledge of the implementation of other modules and without affecting the behavior of other modules The ease of making a change in the design should bear a reasonable relationship to the likelihood of the change being needed The cost of recompiling the body of a module is small The cost of recompiling the interface of a module is relatively high The developer must balance two competing technical concerns: the desire to encapsulate abstractions and the need to make certain abstractions visible to other modules System details that are likely to change independently should be the secrets of separate modules Modules are cohesive (by grouping logically related abstractions) and loosely coupled (by minimizing the dependencies among modules) Define modularity as follows: Modularity is the property of a system that has been decomposed into a set of cohesive and loosely coupled modules. The principles of abstraction, encapsulation, and modularity are synergistic. An object provides a crisp boundary around a single abstraction, and both encapsulation and modularity provide barriers around this abstraction. Two technical issues Modules usually serve as the elementary and indivisible units of software that can be reused across applications, a developer might choose to package classes and objects into modules in a way that makes their reuse convenient Many compilers generate object code in segments, one for each module. Therefore, there may be practical limits on the size of individual modules Nontechnical issues Most important point: Finding the right classes and objects and then organizing them into separate modules are largely independent design decisions. The identification of classes and objects is part of the logical design of the system, but the identification of modules is part of the system’s physical design. One cannot make all the logical design decisions before making all the physical ones, or vice versa; rather, these design decisions happen iteratively. Examples of Modularity In Hydroponics Gardening System Module- Growing plan (FruitGrowingPlan, GrainGrowingPlan) The Meaning of Hierarchy Hierarchy can be defined as follows: Hierarchy is a ranking or ordering of abstractions. The two most important hierarchies in a complex system are its class structure (the “is a” hierarchy) and its object structure (the “part of” hierarchy) Examples of Hierarchy: Single Inheritance Inheritance is the most important “is a” hierarchy and an essential element of object-oriented systems Inheritance defines a relationship among classes, wherein one class shares the structure or behavior defined in one or more classes (denoting single inheritance and multiple inheritance, respectively) Inheritance thus represents a hierarchy of abstractions, in which a subclass inherits from one or more superclasses. Typically, a subclass augments or redefines the existing structure and behavior of its superclasses. Semantically, inheritance denotes an “is a” relationship. For example, a bear “is a” kind of mammal, a house “is a” kind of tangible asset, and a quick sort “is a” particular kind of sorting algorithm. Inheritance thus implies a generalization/specialization hierarchy, wherein a subclass specializes the more general structure or behavior of its superclasses. Indeed, this is the litmus test for inheritance: If B is not a kind of A, then B should not inherit from A. Ex- Hydroponics Gardening System FruitGrowingPlan, GrainGrowingPlan or VegetableGrowingPlan are specialized classes (subclasses) and GrowingPlan is the generalized class (superclass) The structure and behavior that are common for different classes will tend to migrate to common superclasses. Superclasses represent generalized abstractions, and subclasses represent specializations in which fields and methods from the superclass are added, modified, or even hidden. There is a healthy tension among the principles of abstraction, encapsulation, and hierarchy. “Data abstraction attempts to provide an opaque barrier behind which methods and state are hidden; inheritance requires opening this interface to some extent and may allow state as well as methods to be accessed without abstraction” For a given class, there are usually two kinds of clients: objects that invoke operations on instances of the class and subclasses that inherit from the class. Liskov therefore notes that, with inheritance, encapsulation can be violated in one of three ways: “The subclass might access an instance variable of its superclass, call a private operation of its superclass, or refer directly to superclasses of its superclass” In Java and C++, the interface of a class may have three parts: private parts, which declare members that are accessible only to the class itself; protected parts, which declare members that are accessible only to the class and its subclasses; and public parts, which are accessible to all clients. Examples of Hierarchy: Multiple Inheritance Inheritance from multiple superclasses Ex- Flower class and a FruitVegetable class, both subclasses of the class Plant. Third class, FlowerFruitVegetable duplicated information from the Flower and FruitVegetable classes Flowering plants and fruits and vegetables have no superclass, they are stand alone. These are called mixin classes because they are meant to be mixed together with other classes to produce new subclasses. Languages must address two issues for multiple inheritance: clashes among names from different superclasses and repeated inheritance. Clashes will occur when two or more superclasses provide a field or operation with the same name or signature as a peer superclass. Repeated inheritance occurs when two or more peer superclasses share a common superclass. In such a situation, the inheritance lattice will be diamond-shaped In C++, virtual base classes are used to denote a sharing of repeated structures, whereas nonvirtual base classes result in duplicate copies appearing in the subclass Examples of Hierarchy: Aggregation “part of” hierarchies describe aggregation relationships. A garden consists of a collection of plants together with a growing plan. In other words, plants are “part of” the garden, and the growing plan is “part of” the garden. This “part of” relationship is known as aggregation. Any language that supports record-like structures supports aggregation. The combination of inheritance with aggregation is powerful: Aggregation permits the physical grouping of logically related structures, and inheritance allows these common groups to be easily reused among different abstractions. In terms of its “is a” hierarchy, a high-level abstraction is generalized, and a low-level abstraction is specialized. A Flower class is at a higher level of abstraction than a Plant class. In terms of its “part of” hierarchy, a class is at a higher level of abstraction than any of the classes that make up its implementation. Thus, the class Garden is at a higher level of abstraction than the type Plant, on which it builds. Aggregation raises the issue of ownership Garden and plant classes are independent. But GrowingPlan is dependent on Garden class. When instance of Garden class is created, the instance of GrowingPlan is also created. Similarly when Garden object is destroyed, the object of GrowingPlan is also destroyed The Meaning of Typing The concept of a type derives primarily from the theories of abstract data types As Deutsch suggests, “A type is a precise characterization of structural or behavioral properties which a collection of entities all share” The terms type and class interchangeable Type can be defined as follows: Typing is the enforcement of the class of an object, such that objects of different types may not be interchanged, or at the most, they may be interchanged only in very restricted ways. A given programming language may be strongly typed, weakly typed, or even untyped, yet still be called object-oriented. For example, Eiffel is strongly typed, meaning that type conformance is strictly enforced: Operations cannot be called on an object unless the exact signature of that operation is defined in the object’s class or superclasses. The idea of conformance is central to the notion of typing. For example, consider units of measurement in physics. Divide distance by time denotes speed not weight. Similarly divide force by temperature doesn’t make sense but divide force by mass does. There is a dark side to strong typing. Strong typing introduces semantic dependencies such that even small changes in the interface of a base class require recompilation of all subclasses. There are two general solutions to these problems. First, use a type-safe container class that manipulates only objects of a specific class, wherein objects of different types are incorrectly mingled. Second, use some form of runtime type identification; knowing what kind of object to be examining at the moment Runtime type identification should be used only when there is a compelling reason because it can represent a weakening of encapsulation. Polymorphic operations can use runtime type identification As Tesler points out, there are a number of important benefits to be derived from using strongly typed languages: Without type checking, a program in most languages can ‘crash’ in mysterious ways at runtime. In most systems, the edit-compile-debug cycle is so tedious that early error detection is indispensable. Type declarations help to document programs. Most compilers can generate more efficient object code if types are declared Untyped languages offer greater flexibility, but even with untyped languages, as Borning and Ingalls observe, “In almost all cases, the programmer in fact knows what sorts of objects are expected as the arguments of a message, and what sort of object will be returned” In practice, the safety offered by strongly typed languages usually more than compensates for the flexibility lost by not using an untyped language, especially for programming-in-the-large. Examples of Typing: Static and Dynamic Typing The concepts of strong and weak typing and static and dynamic typing are entirely different Strong and weak typing refers to type consistency, whereas static and dynamic typing refers to the time when names are bound to types. Static typing (also known as static binding or early binding) means that the types of all variables and expressions are fixed at the time of compilation; dynamic typing (also known as late binding) means that the types of all variables and expressions are not known until runtime. A language may be both strongly and statically typed (Ada), strongly typed yet supportive of dynamic typing (C++, Java), or untyped yet supportive of dynamic typing (Smalltalk). Polymorphism is a condition that exists when the features of dynamic typing and inheritance interact. Polymorphism represents a concept in type theory in which a single name (such as a variable declaration) may denote objects of many different classes that are related by some common superclass. Any object denoted by this name is therefore able to respond to some common set of operations. The opposite of polymorphism is monomorphism, which is found in all languages that are both strongly and statically typed. Polymorphism distinguishes object-oriented programming from more traditional programming with abstract data types Polymorphism is also a central concept in object-oriented design. The Meaning of Concurrency Every program has at least one thread of control, but a system involving concurrency may have many such threads: some that are transitory and others that last the entire lifetime of the system’s execution. Systems executing across multiple CPUs allow for truly concurrent threads of control, whereas systems running on a single CPU can only achieve the illusion of concurrent threads of control, usually by means of some time-slicing algorithm. Two types of concurrency: heavyweight and lightweight A heavyweight process is one that is typically independently managed by the target operating system and so encompasses its own address space. A lightweight process usually lives within a single operating system process along with other lightweight processes, which share the same address space. Communication among heavyweight processes is generally expensive, involving some form of interprocess communication; communication among lightweight processes is less expensive and often involves shared data. Multiple threads of control have issues as deadlock, livelock, starvation, mutual exclusion, and race conditions At the highest levels of abstraction, OOP can alleviate the concurrency problem for the majority of programmers by hiding the concurrency inside reusable abstractions Black et al. therefore suggest that “an object model is appropriate for a distributed system because it implicitly defines (1) the units of distribution and movement and (2) the entities that communicate” Object-oriented programming focuses on data abstraction, encapsulation, and inheritance where concurrency focuses on process abstraction and synchronization The object is a concept that unifies these two different viewpoints: Each object (drawn from an abstraction of the real world) may represent a separate thread of control (a process abstraction) Such objects are called active In a system based on an object-oriented design the world is consisting of set of cooperative objects, some are active and serve independently Concurrency can be defined as follows: Concurrency is the property that distinguishes an active object from one that is not active. Examples of Concurrency ActiveTemperatureSensor There are three approaches to concurrency in object-oriented design. First, concurrency is an intrinsic feature of certain programming languages, which provide mechanisms for concurrency and synchronization. An active object may create that runs some process concurrently with all other active objects. Second, we may use a class library that implements some form of lightweight processes. Naturally, the implementation of this kind is highly platform-dependent, although the interface to the library may be relatively portable. Third, we may use interrupts to give us the illusion of concurrency. Of course, this requires that we have knowledge of certain low-level hardware details. The Meaning of Persistence An object in software takes up some amount of space and exists for a particular amount of time. Atkinson et al. suggest that there is a continuum of object existence, ranging from transitory objects that arise within the evaluation of an expression to objects in a database that outlive the execution of a single program. This spectrum of object persistence encompasses the following: Transient results in expression evaluation Local variables in procedure activations Own variables [as in ALGOL 60], global variables, and heap items whose extent is different from their scope Data that exists between executions of a program Data that exists between various versions of a program Data that outlives the program Traditional programming languages usually address only the first three kinds of object persistence; persistence of the last three kinds is typically the domain of database technology. “Data that outlives the program” is the case of Web applications where the application may not be connected to the data it is using through the entire transaction execution Frameworks like Microsoft’s ActiveX Data Object for.NET (ADO.NET) have arisen to help address such distributed, disconnected scenarios. Introducing the concept of persistence to the object model gives rise to object-oriented databases. Databases build on proven technology, such as sequential, indexed, hierarchical, network, or relational database models, but then offer to the programmer the abstraction of an object-oriented interface, through which database queries and other operations are completed in terms of objects whose lifetimes transcend the lifetime of an individual program. Java provides Enterprise Java Beans (EJBs) and Java Data Objects. Smalltalk has protocols for streaming objects to and from storage (which must be redefined by subclasses). Persistence deals with more than just the lifetime of data. In object-oriented databases, not only does the state of an object persist, but its class must also transcend any individual program, so that every program interprets this saved state in the same way. Persistence can be defined as follows: Persistence is the property of an object through which its existence transcends time (i.e., the object continues to exist after its creator ceases to exist) and/or space (i.e., the object’s location moves from the address space in which it was created). Applying the Object Model The use of the object model leads us to construct systems that embody the five attributes of well-structured complex systems: Hierarchy Relative primitives (i.e., multiple levels of abstraction) Separation of concerns Patterns Stable intermediate forms Benefits of the Object Model First, the use of the object model helps us to exploit the expressive power of object-based and object-oriented programming languages. Without the application of the elements of the object model, the more powerful features of languages such as Smalltalk, C++, Java, and so forth are either ignored or greatly misused. Second, the use of the object model encourages the reuse not only of software but of entire designs, leading to the creation of reusable application frameworks Third, the use of the object model produces systems that are built on stable intermediate forms, which are more resilient to change. Open Issues Several open issues to effectively apply the elements of the object model: What exactly are classes and objects? How does one properly identify the classes and objects that are relevant to a particular application? What is a suitable notation for expressing the design of an object-oriented system? What process can lead us to a well-structured object-oriented system? What are the management implications of using object-oriented design?

Use Quizgecko on...
Browser
Browser