Chapter 1
Object-oriented model
Overview
This chapter introduces the object-oriented models by comparing the model-standard structured programming and other models that you are familiar with.
Object-oriented model is due to the use of standardized structural programming, in the past practice faces challenges. By clearly understanding these challenges, we can better see the advantages of object-oriented programming and better understand its mechanism.
This chapter will not make you change, becoming an object-oriented method expert. It can't even introduce you to all basic object-oriented concepts. However, it will allow you to heat, prepare for the rest of this book, in order to explain how experts use object-oriented design methods in practice.
In this chapter,
l I will discuss a universal analysis method, functional decomposition.
l I will handle demand problems and emphasize the need for handling changes (programmed disaster!).
l I will describe object-oriented programming models and show their actual use.
l I will point out a special object method.
l I will provide a table on page 21 to list important objects used in this chapter.
Before the object-oriented model: function decomposition
Let us start from a general method developed by inspection software. Suppose I gave you an encoded task to access a shape that is stored in the database and displays these shapes. This task can be naturally imagined naturally by thinking that the steps needed. For example, you may imagine that you will solve this problem by the following steps:
1. List the shape list in the database.
2. Open a list of shapes.
3. A list of lists in accordance with some rules.
4. A single shape is displayed on the display.
You can choose any of these steps and further decompose it. For example, you can decompose step 4:
4A
. Identify the type of shape.
4b. Get the shape of the shape.
4C
. Call the appropriate shape display function and transfer the shape of the shape.
This is called functional decomposition because it breaks down to multiple functional steps. You and I do this, because the child has a small child problem is simpler than the processing of the entire problem. I will use the same method to write a cooking method of marinated noodles, or a bicycle assembly instruction. We are so frequent, so naturally, this method is naturally questionable, so that it is rarely questioned or asks if there is something else.
The problem of functional decomposition is that it does not help us in the future to face the possible changes, the code is beautifully evolved. The need for change is often because I want to add a new amount of change in an existing topic. For example, I may have to deal with new shapes or use new display methods. If I have put all the logicals of those steps to put into a large function or module, then any changes to these steps will result in changes to the function or module.
In addition, it has changed the opportunity to change to errors and programs. Or, as I want to say,
Many bugs are derived from changes in code.
Ter yourself this way. Imagine a moment you want to make a change but afraid to place this change into your code, because you know that you can change the code in other places in a place. Why is this this? Does the code must care about all the functions and know how to use these functions? How do these functions interact between each other? Isn't it a function of excessive details, such as the logic it wants to implement, and what it interacts, and the data it use? For people, trying to think about excessive things at a time, it will easily make mistakes in anything.
No matter how you work hard, no matter how good you have made, you will never get all the needs from users. There are too many unknown factors in the future. Things are changing. Reality is always like this ...
You can't stop changing, but you don't have to conquer it.
Demand problem
Ask the software developers about the needs of users, they always say:
l The demand is incomplete. l The demand is usually wrong.
l The demand (and user) is misleading.
l The demand will not tell you all the story.
What you will never be heard is that "our needs are not only complete, clear, easy to understand, but also give the function we will need in the next five years!".
From the experience of writing software for 30 years, the main thing I have learned about demand is ...
Demand is always changing.
I have learned that most developers always treat this as a bad thing, but very few people write code can have a good demand for changes.
The reason why demand changes is because a set of very simple reasons:
l With the discussion of developers and the new possibilities on the software, users will change the views about what they need.
l With the development of automation software, it becomes more familiar with the problem domain, and the development personnel will change on the problem of problem domain.
l The development environment of the software will change. (5 years ago, who will expect the web development like it today?)
This doesn't mean that you should give up the collection of good needs. This means that we must write code that can contain changes. This also means that we must stop hitting themselves because of natural things (or our customers, because the same reason).
Change is incident! Treat it.
l In addition to the simplest case, no matter how good our initial analysis is done, the demand will always change! l We should change the development process to process changes in more effectively, rather than chamber of change.
Processing changes: use functional decomposition
Let us observe the reality of shapes. How should I write code in order to more easily handle the needs of transformation? I can make it more modular instead of writing a big function.
For example, for steps on page 2
4C
, I call the appropriate shape display function and transmit the shape of the shape. "I may write a module shown in Example 1-1.
Example 1-1 uses modularization to include changes
Function: Display Shape
Input: Type of Shape, Description of Shape
Action:
Switch (Type of Shape)
Case Square: Put Display Function for Square Here
Case Circle: Put Display Function for Circle Here
This way, when I receive a need to show a new shape - such as a triangle, I just need to change this module (but wish so!).
However, this method has some problems. For example, I said that the input of this module is the type and description of the shape. To ensure that all shapes are well operated, it may or may not require a consistent shape description, depending on how I store shapes. If the shape of the shape sometimes stores in a set of dot marbles, what is the result? Can this work?
Modularity must help code easier, and understandability makes the code easier to maintain. But modularity does not always help code processing all possible changes.
For the methods I have used, I found that there are two big problems that can be based on the term low polymerization and high coupling. Steve McConnell gives a wonderful description of cohesive and coupling in the book "Code Complete" book. He said,
l Connotation in a routine "correlation between operation".
Some people will explain the consolidation as clear because the higher the degree of correlation between the operations in the routine, the easier understanding of things.
l Coupling the intensity of the connection between "two routines". Coupling is a supplement to the consolidation. Corporation describes the degree of correlation between the internal content in the routine. Coupling describes the degree of correlation between routines and other routines. Our goal is to create such routines, which have internal complete (high polycast) and slight, direct, visualized, and flexible associations (low coupling) with other routines. Most programmers have such experiences, modifications made in a function or a data in a code area, will have unexpected impact on other codes. This bug is called "harmful side effects". This is because when we get the impact of our we want, we also get other impacts we don't want - bugs! Morse, these bugs are often difficult to find because we will not pay attention to the relationship that leads to side effects (otherwise we will not change in that way).
In fact, this kind of bug makes me get a quite amazing discovery:
In fact, we don't cost a lot of time to fix the bug.
I think we only cost small time to repair bugs in the process of maintaining and debugging. A large amount of time is spent looking for bugs and trying to avoid harmful side effects. Relatively speaking, the real bug repair process is very short!
Since harmful side effects are often the hardest bugs, let a function go to multiple different data items, which will make a change in demand more likely to cause problems.
The devil is in the side effects
l The focus is concentrated on the function. It is likely to cause difficulties in difficult to discover. l In maintenance and debugging, a large amount of time is not spent on the repair, but it costs to find bugs and considering how to avoid harmful side effects that can cause bugs due to repairs.
The use of functional decomposition, changes in change makes it hit hard in software development and maintenance. My attention is basically concentrated on the function. The changes made to a set of functions or data affect other group functions and other group data, which in turn makes other functions must make changes. As a snowball rolled down to the mountains will continue to pick up the snow, focus on the function, causing a series of difficult to avoid changes.
Demand for deformation
In order to find a way to solve changes in demand, we will find out how people do things. Suppose you are a seminar, after your course, people still have any other courses, but they don't know where those courses. Your responsibility is to make sure everyone knows how to participate in the next course.
If you use a structured programming method, you may do this:
1. Get a list of course staff.
2. Everyone in the list:
a. Looking for the next course he wants to participate.
b. Look for the location of the course.
C. Looking for the path from your classroom to the next course.
d. Tell him how to participate in the next course.
Do this requires the following procedures:
1. A method used to get a list of course members.
2. A method used to get every member schedule on the course.
3. A program for guiding from your classroom to any other classroom.
4. A control program that serves every member of the course and performs the required steps for each person.
I don't believe that you will eventually follow this way. On the contrary, you may post out from a classroom to another classroom, tell everyone in the class, "I have posted the location of each course in the classroom, please go to your next classroom according to them. "You will expect everyone to know what they are next, they can find the classroom they should go in the list and follow the instructions of the classroom.
Where is the differences between these methods?
l In the first method - gives everyone clear instructions - you have to care about a lot of details. In addition to anyone else, no one needs to be responsible for anything. You will become crazy! l In the second case, you give a general instruction and expect everyone to find what to do.
The biggest difference in this is the transfer of responsibilities. In the first case, you need to be responsible for everything; in the second case, students need to be responsible for their own behavior. These two situations must achieve the same thing, but their organizational structure is very different.
What impact does this affect?
In order to see the effect of this responsibility, let's take a look at what kind of thing happens when new needs is specified.
Suppose I need a special instruction to give graduate students who participate in this seminar. Suppose they need to collect courses before participating in the next course and bring the assessment results to the workshop office. At this point, I will have to modify the control program to distinguish between graduate students and ordinary students, and give special instructions on graduate students. It is likely that I have to make considerable changes to this program.
However, in the second case (people are responsible for themselves), I will only need to write an additional routine to postgraduate students. That control program will still only need to say, "Go to the next classroom." Everyone will simply follow the right directions or her instructions.
This control program is a significant difference. In the first case, whenever there is a new category student, they need to follow special instructions, the control program has to be modified. In the second case, the new category students will have to be responsible for them.
There are three different things here to cause the above facts.
They are:
l People must be responsible for them, not the control program is responsible for them. (Note, in order to achieve this, a person must know which kind of student he or she is.)
l Control program can talk to different types of people (graduate students and ordinary students) as they are exactly the same.
l The control program does not need to know any special steps that students need to be executed from a class to another class.
To comprehensively understand the meaning, it is very important to establish some terms. In "UML Distilled", Martin Fowler describes three different perspectives during software development. They are described in Table 1-1.
Table 1-1 Perspectives during software development
Perspective Description Concept This Perspective "indicates the concept of the field being studied ... Should draw a small concept model of software that is very concerned or not to achieve its software ..." Specifications "Now we are looking at the software, but we are watching it The interface instead of seeing its implementation. "Implementing now we came to the code level. "This may be the most common perspective, but in many cases, specifications are often a better choice."
Let us look back to see the example of the previous "going to the next classroom". Note that as a tutor, you are on the concept level and people communicate. In other words, you are telling people what you want, not how to do it. However, people to participate in their next courses are very unique. They follow a specific directive while working on the implementation level.
On a level (concept) and on another level (implementation), this leads to the command of the command (teacher) does not need to know what happened, but only know what happened in concept. This is very powerful. Let's take a look at how to use these concepts and use them to write procedures.
Object-oriented model
The center-oriented center is the object. The focus of each thing is concentrated on the object. My code is organized around objects rather than functions.
What is an object? Traditional objects are defined as data with methods (functions in object-oriented terms). Unfortunately, it is very limited in this eye to see the object. I will simply use a better definition (it is on Chapter 8, "Extending our Vision"). When I talk about data of an object, they may be simple, just like numbers or strings, or may be other objects. The advantage of using the object is that I can define things they are responsible for themselves. (Please see Table 1-2.) The object is born to know their type. Its internal data allows them to know what state, while the internal code allows them to operate correctly (ie what is expected.).
Table 1-2 Objects and their responsibilities
Object ...
The duties are ...
student
Know which classroom you are in
Know which classroom knows your next class
From a classroom to the next classroom
teacher
Tell people to go to the next classroom
classroom
Have a location
Direction provider
Give two classrooms, send an instruction from a classroom to another classroom
In this example, I identify the object by looking for the entity in the problem, and by observing what these entities need to identify each object's responsibility (or method). This is consistent with the skills of finding objects and finding methods by looking for nouns in need and by looking for verbs in the demand. I found this skill to be quite limited, and I will show a better way. It is now what we started.
The best way to think about the object is to think it is something that has a responsibility. A good design rule is that the object should be responsible for them and should clearly define those responsibilities. That's why I want to say a student object, one of his duty is to know how to go to a classroom from a classroom.
I can also use the Fowler's view framework to see the object:
l At the concept level, an object is a set of duties.
l At the specification level, an object is a group of methods that can be called by other objects or itself.
l At the implementation level, an object is code and data.
Unfortunately, object-oriented design is always tight and discussing only at achieving levels (via code and data) instead of concepts or specifications. But use the following two ways to think about the object, the same huge power!
Since the object has duties and is responsible for them, then there is a way to tell the object. Remember that objects have data related to yourself and how to implement features. Some methods of an object will be labeled by other objects to be called. The set of these methods is called the PUBLIC interface of the object.
For example, in a classroom, I can write a Student object, which has a method called gotonextClassroom (). I may not need to pass any parameters because every student needs to be responsible for himself. That is to say, he may know:
l How to move.
l How to get any other information to execute this task.
There is only one student at first, from a class to another class of ordinary students. Note that there will be many "ordinary students" in my classroom (my system). But what if I want more kinds of students? Let each class of students have a group to tell you what he can do, which seems to be inefficiencies, especially for all students' common tasks.
A more efficient way is to associate all students and a group of methods, each class can use or crop these methods to meet their needs. I will define a "universal student" to include the definition of these public methods. In this way, I have all kinds of students, and each kind of student has to track him or her own private information.
With object-oriented terms, this general student is called a class. A class is a definition of an object behavior. It contains a complete description:
l Object contained data elements
l Objects can be performed on the form of these data elements and methods can be accessed
Because of an object's data element varies, each object of the same type will have different data, but there is the same function (defined in the method).
To get an object, I tell the program that I need this type of object (ie the class belonging to the class belonging). This new object is called an example of such a class. An instance of the creation class is referred to as instantiation.
An example program that uses an object-oriented way to write "Go to the next classroom" will be more simple. This program looks like:
1. Start the control program.
2. Instantiate the student collection in the classroom.
3. Tell the collection to let students go to their next classroom.
4. This collection tells every student to go to their next classroom.
5. Every student:
a. Which classroom is looking for his next course?
b. Decide how to go there
c. Go there
6. end.
The above is running well until I need to add another student type, such as graduate students.
Trouble. It seems that I have to allow any type of student to enter the collection (whether ordinary students or graduate students). The question I face is how to let the collection access to its elements. Since I talk about the code implementation, then this collection will actually be an array or a thing with a certain type of object. If you name it as regularStudents, I will not be able to place GraduateStudents. If this collection is just a set of objects, how can I guarantee that I will not put the wrong type object (ie, "going to the next classroom")?
The way is very simple. I need a generic type that contains more than one specific type. I need a Student type that contains RegularStudents and GraduateStudents. Using object-oriented terms, we call Student as an abstract class.
The abstract class defines what other related classes can do. These "other" classes are classes representing a particular kind of behavior. Such a class is often referred to as a specific class because it represents a specific, or constant implementation of the concept.
In this example, the abstract class is Student. The specific class RegularStudents and GraduateStudents represent two types of Student. The former is a class of students, the latter is also a type of student.
This relationship is referred to as IS-A, which formally referred to as inheritance. That is, the RegularStudents class inherits from Student. Other statements, GraduateStudents inherited from self-contained, or a subclass of Student.
For a way, Student is generalized in RegularStudents and GraduateStudents, or their base class or superclass.
Abstract classes are other class placeholders. I use them to define methods that derived class must implement. Abstract classes can also include common methods used by all derived classes. Regardless of whether a derived class is used by default or with their own behavior, it is until it is to this, and the object must be consistent with the other person responsible for them.
This means that I can make the controller contain students. We use Student as a reference type. The compiler can detect anything that is referenced by this Student reference is a Student. This gives the biggest benefits in the two worlds:
l This collection only needs to handle Student (thus allowing the teacher object to deliver only the Student).
l Yes, I can still get the benefits of type detection (only those who can "go to the next classroom").
l Any Student requires its functionality just in its own way.
Abstract classes are not just a class that is not initialized
Abstract classes are often described as a class that is not initialized. Such definitions are precise - in the implementation level. But it is very limited. Defining an abstraction class is more useful in a conceptual level, where they are simple placeholder symbols of other classes. That is to say, they give us a method to give a name for a group. This allows us to treat this group as a concept. In object-oriented models, you must constantly think about problems from three viewing levels.
Because objects must be responsible for them, there are many things that do not have to be exposed to other objects. I have previously mentioned the concept of public interface - those methods that can be accessed by other objects. In an object-oriented system, the main access types are:
l Public - Anything can see it.
l Protected - the object that only this class and its derived class can see it.
l Private - Only the object of this class can see it.
This will lead the concept of packaging. The package is often described as a data hide. Objects usually do not expose their internal data members to the external world (ie their visibility is protected or private).
But the package is not just data hidden. In general, packaging means any form hidden.
In this example, the teacher does not know which is a general student, which is a graduate student. The type of student is hidden by the teacher (I am packing the type of student). As you will see later, this is a very important concept.
Another term to be learned is a polymorphism.
In an object-oriented language, we often mention the object of abstract class types. However, in fact, we refer to a specific example of the class that is derived from these abstract classes.
Therefore, when I conceptually tell the object to do something conceptually, I will get different behaviors. The word Polymorphism is derived from Polymorph (Morphology), so it means a variety of forms. This is a suitable name because I will get a lot of different forms of behavior for the same call.
In this example, the teacher told the students "Go to the next classroom." Relying on the type of student, they will show different behavior (polymorphism).
Object-oriented terminology review
the term
description
Objects an entity with responsibilities. Realize your duties by writing a class defining a class (with the variable) and the method (and the function associated with the object). Class method warehouse. Define the data member of the object. The code is organized around the class. The package is typically defined as a data hide. But it is considered to be better in any form. Inherit is a special type of a class into another class. These specialization classes are called the base class (initial class) derived. The base class is sometimes referred to as superclars, and the derived class is sometimes referred to as subclasses. A special example of an instance class (it is always an object). Instantiate the process of creating an instance of a class. Polymorphisms can reference a class of different derivative classes through the same method to obtain and be suitable for the active students. The perspective has three different perspectives of the object: concept, specification and implementation. These differences help to understand the relationship between abstract classes and their derivatives. Abstract classes define how to solve problems conceptually. It simultaneously defines the specifications of any derived object communication with it. Each derived class provides the particular implementation required.
Object-oriented programming
Let's re-examine the shape example of the beginning of this chapter. How will I use the object-oriented way to implement it? Remember, we have to do this:
1. List the shape list in the database.
2. Open a list of shapes.
3. This list is arranged in accordance with certain rules.
4. The shape is displayed on the monitor one by one.
In order to solve this problem in an object-oriented manner, I need to define the following objects and their responsibilities.
The object I need is:
class
Responsibilities (method)
Shapedatabase
getCollection - get a set of specified shapes
Shape (Abstract Class) Display- Defining Shape Interface
Getx- Returns the x position of Shape (for sorting)
gety- Returns the Y position of Shape (for sorting)
Square (derived from shape)
Display- Display a square (representative of this object)
Circle (derived from Shape)
Display- Show a circle (represented by the object)
COLLECTION
Display- tells the shape contained in the shape
Sort- Sorting this shape collection
DISPLAY
Drawline - draw a straight line on the screen
Drawcircle - draw a circle on the screen
The main program looks as follows:
1. The main program creates an instance of the database object.
2. The main program requests the database object to find the shape set I am interested in and initialize a collection object containing all shapes (in fact, it will instantiate the circle and squares included in the collection).
3. The main program request set the collected shape.
4. The main program request set the display shape.
5. The collection requests it contains each shape displaying yourself.
6. Depending on my shape type, each shape shows yourself (using Display object).
Let us see how this helps us deal with new demand (remember, demand is always changing). Consider the following new needs:
Add new types of shapes (such as triangles). To introduce a new shape, only two steps are required:
- Create a new derived class for Shape to define this shape.
- In the new derived class, a version suitable for this shape is implemented for the Display method.
Changing the sorting algorithm. In order to change the shape of the shape, just one step:
- Modify the method of Collection. Each shape will use a new algorithm.
Bottom line: Object-oriented method limits the impact of demand changes.
Package brings several advantages. It directly means that the facts that isolate things with users:
l Use things more simple because users don't need to worry about their implementation details.
l Allow changes to the change without worrying for the caller. (Because the caller doesn't know how it is implemented, there is no dependency.)
l The inside of an object is unknown for external objects - they are used by this object to help implement the functions specified by the object interface.
Finally, let's consider the problem of adverse side effects that appear when the function changes. Using a package, we can effectively handle this class of bugs. If I use a package and follow the object for the strategy for their own responsibility, the only way to affect the object is a method of calling the object. The data of this object and the changes that implement their responsibilities and changes in other objects will be shielded.
The package rescued us lick, the more the object is responsible for their own behavior, the less the control program needs to be responsible. l The encapsulation makes a change in an object's internal behavior transparent to other objects. l Package help prevent adverse side effects.
Specific object method
I have already talked about the ways that were called by other objects or objects. But what happens when the object is created? What happens when they destroy? If the object is a self-contained unit, it will be a good idea to deal with these situations.
In fact, these special methods are present, they are referred to as constructor and destructor.
The constructor is a special method that is automatically called when the object is created. Its purpose is to deal with the start of the object. This is some of the object being forced to be part of itself. The constructor is born to be an initialization, setting the default parameters, established and other objects, or do anything that helps to generate a good definition. All object-oriented languages will find a constructor and execute when the object is created. We can easily eliminate (or at least reduced) uninitialized variables by properly using constructor. Such errors are usually generated due to the accident of developers. This is easier to ensure initialization occurrence by using a consistent place in the entire code (the constructor of the object). The error caused by uninitialized variables is easy to repair but it is difficult to find that such a convention (automatic call constructor) can improve the efficiency of programmers.
The designer function is a special method that helps an object to clean up when it does not exist, ie when it is destroyed. All object-oriented languages are looking for a destructor and execute when an object is deleted. Like constructor, the use of the destructor is also a part of the object being forced to be its own.
The designer function is typically used to release resources when the object is no longer needed. Since Java has a garbage collection mechanism (automatic cleaning is no longer used object), the monographic function is not as important as in C in Java. The information function in the C will also destroy other objects that are only used by the object, which is very common.
to sum up
In this chapter, I showcase how objects help us reduce the impact of the conversion system demand, and compare it with functional decomposition.
I involve some important concepts in object-oriented programming, and introduces them, describing the basic terms. These are critical to understanding the concepts of this book. (See Table 1-3 and 1-4.)
Table 1-3 Object-Oriented Concept
concept
review
Functional decomposition
Structured programmers often use functional decomposition to program. Functional decomposition will be split into a smaller function. Each feature is subdivided until manageable.
Demand change
Demand changes are inherent characteristics of the development process. It is impossible to use it that it is impossible to accuse the user or you can't win the collection and complete demand. It is better to use the development method that can more effectively handle demand changes.
Object
The object is defined by its responsibilities. By being responsible for yourself, the object simplifies the task of using their programs.
Constructor
And destructor
The object has a special way, they are called when the object is created and deleted. These special methods are:
l Constructor, which initializes or sets an object.
l Destructor, it cleans the object when the object is deleted.
All object-oriented languages use constructor and destructive functions to help manage objects.
Table 1-4 Object-oriented terminology
the term
definition
Abstract class
Define methods and common properties of a set of concepts similar classes. Abstract classes will never be instantiated.
Attributes
Data associated with an object (also known as data member).
class
Object Blueprint - Defines the method and data of the object.
Constructor
Special methods are called when the object is created.
Encapsulate
Any form of hidden. Objects encapsulate their data. Abstract class packages are derived by them.
Destructor
Special methods are called when the object is deleted.
Functional decomposition
An analysis method that splits the problem into a smaller function.
inherit
The method of specialization is used to associate derived classes and their abstraction classes.
Example
A specific object of the class.
member
Class data or method.
Object
An entity with responsibilities. A special self-contained data, the holder of the method of operating data. The object's data is protected from damage to the external object.
Polymorphism
The ability of related objects to achieve special methods for their types.
Superfine
A class, other classes are derived from it. Contains all derived classes will use the main properties and methods of (and possibly overwriting).