|
Thoughts on Coding Methodologies
How to communicate, think, plan, design, programme and code BY JOHN JAN POPOVIC
Thoughts on Coding Methodologies
------------------------------------------------------- REFINEMENT OF THE PRODUCT REQUIREMENTS ------------------------------------------------------ “The hardest single part of building a software system is deciding what to build. No other part of the conceptual work is as difficult in establishing the detailed technical requirements, including the interfaces to people, to machines, and to other software systems. No other part of the work so cripples the results if done wrong. No other part is more difficult to rectify later. Therefore, the most important function that the software builder performs for the client is the iterative extraction and refinement of the product requirements.” —Fred Brooks
----------------------------- DATA AT THE BEGINNING ----------------------------- At the beginning I am focused on data repositories, all files in the system, and their data records structure. And what must be done in order to process input files into desired output behaviour and data. What are the test scenarios, and if the customer has provided test data together with requirements?
------------------------------- GENERAL SPECIFICATIONS ------------------------------- In this early stage it is clear : - what are the files in the system repository, and what is their record structure - what is desired behaviour of the software modules and objects - feature specification list - test data and test scenarios / input and desired output Customer must be aware that in general lines, the software requirements should be set in stone before Development CYCLUS begins, in order not to wasted work put into a design and development based on incorrect requirements.
--------------------------------------------------------------------------------- ROADMAP DEVELOPMENT PLANNING, TRACKING AND THE TRADE OFFS --------------------------------------------------------------------------------- The primary planning task is providing recommended short term, intermediate, and long term strategic goals, and lay out MILESTONE objectives. This ROADMAP includes implementation milestones, cycles phases, schedules, potential costs, etc. for the activities which should ensure harmonization with the customer plans and successful implementation and deployment of milestones.
------------------------- ROADMAP REVISIONS ------------------------- If desired, the order of the MILESTONES can even be altered to suit the particular needs of the planning team. The implementation step also does not end the planning process. Analysis of results could easily result in additional analysis or a change in strategic direction. Also, it is recommended that the plan be reviewed periodically, sometimes even on a daily basis in order to verify that all the base assumptions are still valid and that the implementation plan is progressing according to expectations. The secondary planning task is providing alternatives, trade-offs, and constraints in implementing a scalable performance-based system. To buy, to built, to outsource or rent the service or solution. THAT IS THE QUESTION? . implementation of improvements in the... planning support that includes Operations Evolution -- safety, policy, procedures,...
---------------------------------------------------------- Early prototype of risky or unfamiliar parts of the system ---------------------------------------------------------- Have you prototyped risky or unfamiliar parts of the system, creating the absolute minimum amount of throwaway code needed to answer specific questions?
Divide and Conquer As Edsger Dijkstra pointed out, no one's skull is big enough to contain all the details of a complex program, and that applies just as well to design. Divide the program into different areas of concern, and then tackle each of those areas individually. If you run into a dead end in one of the areas, iterate! Incremental refinement is a powerful tool for managing complexity. As Polya recommended in mathematical problem solving, understand the problem, devise a plan, carry out the plan, and then look back to see how you did (Polya 1957). Design is an iterative process. You don't usually go from point A only to point B; you go from point A to point B and back to point A. Virtually all systems undergo some degree of design changes during their initial development, and then they typically change to a greater extent as they're extended into later versions. The degree to which change is beneficial or acceptable depends on the nature of the software being built.
------------------------------ Grow, Don't Build ------------------------------
Create a tiny seed of working code that can grow into what you desire. The critical phase for a project is the single-developer phase when one person has to get the program to do something that other stockholders will find it somewhat useful. Working software is constantly released in a sequence of tiny iterative and incremental commits — becoming progressively more useful as it is developed.
Successful projects evolve like living, growing things, through a series of tiny changes forming a continuum of commits in a "constant release". It is opposed to an engineered machine built from pieces which come together into a single "product".
Don't try to engineer a "perfect" solution and then get team members to cooperate with you on developing it. In practice, very few people will contribute to a project that has no working code.
It is much better to have a small, compartmentalized software component which performs perfectly and it is part of a complex IT system. Exchange of data and messages among individual software components must always be monitored and traced via comprehensive LOG reports.
Doug McIlroy, then head of the Bell Labs, and inventor of the Unix pipe, summarized the Unix philosophy as follows: - Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface. -------------------------------------------------------------------------------------- ------------------ PHILOSOPHY ------------------ • We start with a vague and move toward precise project definition
• “In software, we rarely have meaningful requirements. Even if we do, the only measure of success that matters is whether our solution solves the customer’s shifting idea of what their problem is.” (Jeff Atwood)
• We start with very simple but working software, to which we add features, as we move on on the roadmap
• “First, solve the problem. Then, write the code.” (John Johnson)
• We start with simple code with crippled functionality, which is refined and improved until excellency is achieved
• “Simplicity, carried to the extreme, becomes elegance.” – Jon Franklin
• “Controlling complexity is the essence of computer programming.”
• "Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it" (Brian Kernigan)
• I go forward in small incremental steps, implement a little code at the time, creating a Simple Test Case scenario, and figure out how I can test it if it is correct
• “Complexity kills. It sucks the life out of developers, it makes products difficult to plan, build and test, it introduces security challenges, and it causes end-user and administrator frustration.” (Ray Ozzie)
• “There are two ways of constructing a software design. One way is to make it so simple that there are obviously no deficiencies. And the other way is to make it so complicated that there are no obvious deficiencies.” (C.A.R. Hoare)
• “The function of good software is to make the complex appear to be simple.” (Grady Booch)
• “Good code is its own best documentation.” (Steve McConnell)
• “Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are–by definition–not smart enough to debug it.” (Brian Kernighan)
• “If debugging is the process of removing bugs, then programming must be the process of putting them in.” (Edsger W. Dijkstra)
------------------ METHODOLOGY ------------------ Feature driven development FDD Process is applied for the development of an Overall Model > For 0.1 alfa verson of the software I will start by creating really elementary application, with some simple and already well understood CORE features by reusing previously developed code. And I will try to implement all Data Stuctures relevant for the system repositories, upon which the new features will be developed and deployed in the future. From the customer wish-list, formal requirements specification will be produced; which will evolve into features list. Then a rough plan is drawn up and responsibilities assigned. Now we are ready to repeatedly take small groups of features through a design and build iteration that lasts from several hours up to couple of weeks in rare cases.
----------------------------- Test driven development ----------------------------- For some difficult features I apply a TDD - test driven development methodology. I go forward in small incremental steps, create a Simple Test Case scenario, implement a little code at the time and figure out how I can test it if it is correct; create more difficult Test case and reiterate that process until I have a strong and robust Error reporting system with possible corrective patterns. The point is that you try to see what could go wrong if you insert incorrect input parameters, and if it will be correctly reported or just ignored, or if the system will crush. When I am sure that this feature works fine, and fails gracefully and reports the error correctly; I clean up the code and comment it.
My approach is adaptable, allowing me to engage and provide testable solutions at any stage in the software development life-cycle. From planning and pre-definition strategy to post-release usability. I blend a variety of methods and best practices. This allows me to create valuable and testable solutions in every stage of the development.
Writing the tests FIRST can prevent defects from entering the code and that is more efficient than introducing, finding, and then fixing bugs, afterwords.
All tests verify that the code works as expected, but some tests can be part of specifications of how yet-to-be-written code should work. In the latter situation, the tests can be an important tool for communicating how the application should behave. . What I really do not like is Big Design Up Front (BDUF) development approach in which the software design must be completed and perfected before the coding starts. It is often associated with the Waterfall Model. Big Design Up Front (BDUF) is a term for any software development approach in which the program's design is to be completed and perfected before that program's implementation is started. It is often associated with the waterfall model of software development.
Otherwise my design at the beginning is often vague and general, for not having the clear picture, and since often the problem assignment is not well defined in advance by the customer. Often at the beginning, only what I have is only a vague impression of the assignment versus a precise one customer is not able to provide.
----------------------------- Disaster planning -----------------------------
To be proactive, you should thoroughly plan methods for solving known errors and incidents, and predict a general catastrophe. This is called contingency planning or disaster planning.
True to form, if you are ready and prepared for undesired situation, then you do not need to worry if they happen. It's like having a full hull insurance policy - and you have a plan B, whatever happens you can keep cool.
|
|