OO development is a rather unique approach to software development that emphasizes problem space abstraction. It is less intuitive than procedural or functional programming approaches that are based directly upon the organization of computers and the computational models of Turing and von Neumann. However, its close mapping to the customer problem space tends to provide a long-term stability for applications. In addition other techniques combine with problem space abstraction to produce more maintainable software.
The primary difference between OO development and procedural or functional development lies in the role of sequences of operations in the development. In procedural or functional development one focuses initially on such sequences and decomposes them into program units. While the specific mode of decompostiion varies, the development is still driven by analyzing sequences of operations.
In contrast, OO development begins with creating a static view of the problem space. That view is elaborated with more detail until one has a complete skeleton for the application. Only then does one deal with the dynamics of the solution and then it is highly localized. Only in the final step does one deal with the specific flow of control of the overall problem solution. Fundamentally the OO approach answers five questions in order:
(A) What problem space entities are involved in the solution to the problem in hand?
(B) What intrinsic responsibilities do those entities have that are necessary to solve the problem in hand?
(C) What logical relationships to the entities have with each other on a peer-to-peer basis?
(D) What do the entities actually need to do to solve the problem in hand?
(E) What are the collaborations between entities that are necessary to solve the problem in hand?
Thus the basic steps in OO development approach are:
(1) Identify the the problem space entities that are relevant to the problem solution. While doing so we relate similar entities into sets that we identify as classes. Basically this means providing classifier boxes on a UML Class Diagram. The key mapping here is that the entities must be readily identifiable in the problem space. They may be conceptual rather than tangible, but they must be readily recognized by any domain expert.
(2) Identify the intrinsic responsibilities each entity has that are relevant to the problem in hand. In OO development responsibilities are defined in terms of knowing something (knowledge) and doing something (behavior). In this step one does not care how they know or do these things; one just identitifies the responsibilities. Very commonly behavior responsibilities are anthropomorphized as entity roles. That's because software replaces things that people do but we rarely model people directly; instead we model things and concepts in the problem space. So we must allocate the things that the replaced people would do as behavior responsibilities of the entities identified in (1). This is also done on a UML Class Diagram.
[This is perhaps the most fundamental difference between OO and procedural/functional development. In procedural/functional development one goes directly to what people do and captures those activities as procedures. Procedures are then collected into program units that roughly correspond to the people in the problem space. Those units are then named with the role the person person plays in the solution, such as XxxManager or XxxController. In the OO approach one only abstracts entities that are tangible or conceptual outside the context of individual people. That's because such entities are more stable than people's roles so they provide a more stable long-term architecture for the application.]
(3) Identify fundamental relationships between sets of entities (classes). These relationships define the structure of participation in interactions between members of the sets. In effect, they place constraints on what members of another set a member of the set in hand can interact with. That is, relationships define very basic static (invariant) limits on participation in collaborations. This is also done on a UML Class Diagram.
(4) Define the intrinsic behaviors of the entities that resolve their behavior responsibilities. The operative word here is intrinsic. One defines what the entities do without direct regard for the overall solution context. In particular, individual behavior responsibilities are resolved without any dependence upon other entity behaviors. In effect the step is about abstracting behavior in a manner that is tailored to the problem in hand without undue consideration of specific solution flow of control. This will be done with UML Statecharts and/or synchronous methods where the actual activities are described with an abstraction action language.
(5) Define collaboration messages. Essentially this connects the behavioral dots by defining who sends messages and who receives them. The sequencing of messages defines the overal problem solution's flow of control. In UML this is typically done on one of the Interaction Diagrams.