Wednesday, April 11, 2012

Growing Object Oriented Software, Guided by Tests–Extracts

Source: Growing Object Oriented Software, Guided by Tests

Roles, Responsibilities, Collaborators

We try to think about objects in terms of roles, responsibilities, and collaborators, as best described by Wirfs-Brock and McKean.

  • An object is an implementation of one or more roles;
  • a role is a set of related responsibilities;
  • and a responsibility is an obligation to perform a task or know information.
  • A collaboration is an interaction of objects or roles (or both).

Sometimes we step away from the keyboard and use an informal design technique that Wirfs-Brock and McKean describe, called CRC cards (Candidates, Responsibilities, Collaborators). The idea is to use low-tech index cards to explore the potential object structure of an application, or a part of it. These index cards allow us to experiment with structure without getting stuck in detail or becoming too attached to an early solution.

Tell, Don’t Ask

We have objects sending each other messages, so what do they say? Our experience is that the calling object should describe what it wants in terms of the role that its neighbor plays, and let the called object decide how to make that happen.

This is commonly known as the “Tell, Don’t Ask” style or, more formally, the Law of Demeter. Objects make their decisions based only on the information they hold internally or that which came with the triggering message; they avoid navigating to other objects to make things happen. Followed consistently, this style produces more flexible code because it’s easy to swap objects that play the same role. The caller sees nothing of their internal structure or the structure of the rest of the system behind the role interface.

Designing for Maintainability

We grow our systems a slice of functionality at a time. As the code scales up, the only way we can continue to understand and maintain it is by structuring the functionality:

  • into objects,
  • objects into packages,
  • packages into programs,
  • and programs into systems.

We use two principal heuristics to guide this structuring:

Separation of concerns

When we have to change the behavior of a system, we want to change as little code as possible. If all the relevant changes are in one area of code, we don’t have to hunt around the system to get the job done. Because we cannot predict when we will have to change any particular part of the system, we gather together code that will change for the same reason. For example, code to unpack messages from an Internet standard protocol will not change for the same reasons as business code that interprets those messages, so we partition the two concepts into different packages.

Higher levels of abstraction

The only way for humans to deal with complexity is to avoid it, by working at higher levels of abstraction. We can get more done if we program by combining components of useful functionality rather than manipulating variables and control flow; that’s why most people order food from a menu in terms of dishes, rather than detail the recipes used to create them.

Encapsulation and Information Hiding

We want to be careful with the distinction between “encapsulation” and “information hiding.” The terms are often used interchangeably but actually refer to two separate, and largely orthogonal, qualities:

Encapsulation

Ensures that the behavior of an object can only be affected through its API. It lets us control how much a change to one object will impact other parts of the system by ensuring that there are no unexpected dependencies between unrelated components.

Information hiding

Conceals how an object implements its functionality behind the abstraction of its API. It lets us work with higher abstractions by ignoring lower-level details that are unrelated to the task at hand.

We’re most aware of encapsulation when we haven’t got it. When working with badly encapsulated code, we spend too much time tracing what the potential effects of a change might be, looking at where objects are created, what common data they hold, and where their contents are referenced.

Object Peer Stereotypes

We have objects with single responsibilities, communicating with their peers through messages in clean APIs, but what do they say to each other?

We categorize an object’s peers (loosely) into three types of relationship. An object might have:

Dependencies

Services that the object requires from its peers so it can perform its responsibilities. The object cannot function without these services. It should not be possible to create the object without them. For example, a graphics package will need something like a screen or canvas to draw on—it doesn’t make sense without one.

Notifications

Peers that need to be kept up to date with the object’s activity. The object will notify interested peers whenever it changes state or performs a significant action. Notifications are “fire and forget”; the object either knows nor cares which peers are listening. Notifications are so useful because they decouple objects from each other. For example, in a user interface system, a button component promises to notify any registered listeners when it’s clicked, but does not know what those listeners will do. Similarly, the listeners expect to be called but know nothing of the way the user interface dispatches its events.

Adjustments

Peers that adjust the object’s behavior to the wider needs of the system. This includes policy objects that make decisions on the object’s behalf (the Strategy pattern) and component parts of the object if it’s a composite. For example, a Swing JTable will ask a TableCellRenderer to draw a cell’s value, perhaps as RGB (Red, Green, Blue) values for a color. If we change the renderer, the table will change its presentation, now displaying the HSB (Hue, Saturation, Brightness) values.

Interface and Protocol

An interface describes whether two components will fit together, while a protocol describes whether they will work together.

Thursday, March 22, 2012

The Art of Readable Code – Extracts

Source: The Art of Readable Code–Extracts

Basic Rules:

  • Code should be easy to understand.
  • Code should be written to minimize the time it would take for someone else to understand it.

Surface-Level Improvements

  • Picking good names,
  • Writing good comments,
  • Formatting your code neatly

About names

The best names are ones that can’t be misconstrued—the person reading your code will understand it the way you meant it, and no other way. Unfortunately, a lot of English words are ambiguous when it comes to programming, such as filter, length, and limit.
Before you decide on a name, play devil’s advocate and imagine how your name might be misunderstood. The best names are resistant to misinterpretation.

  • Packing Information into Names
  • Choosing specific words
  • Avoiding generic names (or knowing when to use them)
  • Using concrete names instead of abstract names
  • Attaching extra information to a name, by using a suffix or prefix
  • Deciding how long a name should be
  • Using name formatting to pack extra information

Naming Booleans

When picking a name for a boolean variable or a function that returns a boolean, be sure it’s clear what true and false really mean.

In general, adding words like is, has, can, or should can make booleans more clear.

It’s best to avoid negated terms in a name.

Lines of code

Instead of minimizing the number of lines, a better metric is to minimize the time needed for someone to understand it.

Variables

  1. The more variables there are, the harder it is to keep track of them all.
  2. The bigger a variable’s scope, the longer you have to keep track of it.
  3. The more often a variable changes, the harder it is to keep track of its current value.

Functions

  1. Look at a given function or block of code, and ask yourself, “What is the high-level goal of this code?”
  2. For each line of code, ask, “Is it working directly to that goal? Or is it solving an unrelated subproblem needed to meet it?”
  3. If enough lines are solving an unrelated subproblem, extract that code into a separate function.

One task at a time

Here’s the process we use to make code do “one task at a time”:

  1. List out all the “tasks” your code is doing. We use the word “task” very loosely—it could be as small as “make sure this object is valid” or as vague as “iterate through every node in the tree.”
  2. Try to separate those tasks as much as you can into different functions or at least different sections of code.

Sunday, March 18, 2012

Quotes

“Luck favors the prepared mind only” - Louis Pasteur

”Success and rest don’t sleep together. “- Russian proverb

”About motivate problematic people:  create a rich picture, reframe your goals, stage the encounter”

“Reasonable people adapt themselves to the world. Unreasonable people attempt to adapt the world to themselves. All progress, therefore, depends on unreasonable people.”
— George Bernard Shaw, an Irish playwright and a co-founder of the London School of Economics.

“Tact is the art of making a point without making an enemy.”
— Howard W. Newton, an American advertising executive and author.

“To avoid criticism do nothing, say nothing, be nothing.”
— Elbert Hubbard, an American writer, publisher, artist, and philosopher

“An expert is a person who has made all the mistakes that can be made in a very narrow field.”
— Niels Bohr

“Victorious warriors win first and then go to war, while defeated warriors go to war first and then seek to win.”
Sun Tzu

“Intellect distinguishes between the possible and the impossible; reason distinguishes between the sensible and the senseless. Even the possible can be senseless.”
Max Born

“When I’m working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong.”
— Buckminster Fuller, an American engineer

"Good managers motivate with the power of their vision, the passion of their delivery, and the compelling logic of their reasoning"

“A man speaks with his heart, thinks with the history and lives to change it” – Nibor

Architecture

Architecture is about looking at a system from a point of view that makes it appear simple, sometimes artificially so. It provides a way of looking at the "conceptual essence" of something without getting bogged down in every detail.

An architectural viewpoint

It has to be simple to understand, to describe, to compare with other viewpoints, and, ultimately, to implement.
The viewpoint might seek a broad approach to a big, sweeping problem. Then again, it might be a thematic idea that can generate a family of similar solutions to a crowd of similar little problems—that is, a design pattern.

Adopting such a viewpoint inevitably limits one's implementation choices. That can be good. If all options are open, ten similar problems in your project might get solved using ten different techniques. That can require up to ten times more work than solving them all with a single technique, outweighing the usually meager benefits of handcrafting each solution. It can take up to ten times as much effort for a new developer to understand how the code works. And when it comes time to change the approach(es), it might take up to ten times as much effort to make that change (since you'd have ten different starting points). So, limiting variation saves time, makes things much easier to understand, and lets you discover and factor out common code much more easily.

When we simplify enough, and in the right way, we wind up with a viewpoint that contains a small number of concepts to think about, each of which has a clear set of responsibilities, relationships, and interactions with the others. It points the way forward on multiple fronts. A viewpoint like that is usually a sign of a successful architecture.

Made to Stick: Why Some Ideas Survive and Others Die–Extracts

Source: Made To Stick

Making your ideas sticky

What's my point? And why does it matter? If your audience remembers only one thing, what should it be?

Process for making your ideas stickier

  1. Identify the central message you need to communicate—find the core;
  2. Figure out what is counterintuitive about the message —i.e., What are the unexpected implications of your core message? Why isn't it already happening naturally?
  3. Communicate your message in a way that breaks your audience's guessing machines along the critical, counterintuitive dimension. Then, once their guessing machines have failed, help them refine their machines.

Principles

  1. Simplicity. The Golden Rule Is The Ultimate Model Of Simplicity: A One-sentence Statement So Profound That An Individual Could Spend A  Lifetime Learning To Follow It.
  2. Unexpectedness
  3. Concreteness
  4. Credibility
  5. Emotions
  6. Stories

Steps

There are two steps in making your ideas sticky-

  1. is to find the core, and
  2. is to translate the core using the SUCCESs checklist.

The Zen aesthetic values include (but are not limited to):

  • Simplicity (Kanso)
  • Subtlety
  • Elegance (Shibumi)
  • Suggestive rather than the descriptive or obvious
  • Naturalness (Shizen)(i.e., nothing artificial or forced),
  • Empty space (or negative space)
  • Stillness, Tranquility
  • Eliminating the nonessential

Facts

  • Simple messages are core and compact.
  • People will attempt to change their behavior if
    they believe it will be worth it, and
    they can do what is required.
  • Remember, stories need to deal with both
    “Will it be worth it?” and “Can I do it?” When it comes to changing behavior, nothing else matters

Monday, January 30, 2012

The Mythical Man-Month – Extracts VII

Source: The Mythical Man-Month

Importance of Milestones  in Big Projects

How does one control a big project on a tight schedule? The first step is to have a schedule. Each of a list of events, called milestones, has a date. Picking the dates is an estimating problem, discussed already and crucially dependent on experience.

For picking the milestones there is only one relevant rule. Milestones must be concrete, specific, measurable events, defined with knife-edge sharpness. Coding, for a counterexample, is "90 percent finished" for half of the total coding time. Debugging is "99 percent complete" most of the time. "Planning complete" is an event one can proclaim almost at will.

Concrete milestones, on the other hand, are 100-percent events. "Specifications signed by architects and implementers," "source coding 100 percent complete, keypunched, entered into disk library," "debugged version passes all test cases." These concrete milestones demark the vague phases of planning, coding, debugging.

Two interesting studies of estimating behavior by government contractors on large-scale development projects show that:

  1. Estimates of the length of an activity, made and revised carefully every two weeks before the activity starts, do not significantly change as the start time draws near, no matter how wrong they ultimately turn out to be.
  2. During the activity, overestimates of duration come steadily down as the activity proceeds.
  3. Underestimates do not change significantly during the activity until about three weeks before the scheduled completion.

Sharp milestones are in fact a service to the team, and one they can properly expect from a manager. The fuzzy milestone is the harder burden to live with. It is in fact a millstone that grinds down morale, for it deceives one about lost time until it is irremediable. And chronic schedule slippage is a morale-killer.

Under the rug

When a first-line manager sees his small team slipping behind, he is rarely inclined to run to the boss with this woe. The team might be able to make it up, or he should be able to invent or reorganize to solve the problem. Then why worry the boss with it? So far, so good. Solving such problems is exactly what the first-line manager is there for. And the boss does have enough real worries demanding his action that he doesn't seek others. So all the dirt gets swept under the rug.

But every boss needs two kinds of information:

  • Exceptions to plan that require action and
  • Status picture for education. For that purpose he needs to know the status of all his teams. Getting a true picture of that status is hard.

The first-line manager's interests and those of the boss have an inherent conflict here. The first-line manager fears that if he reports his problem, the boss will act on it. Then his action will preempt the manager's function, diminish his authority, foul up his other plans. So as long as the manager thinks he can solve it alone, he doesn't tell the boss.
Two rug-lifting techniques are open to the boss. Both must be used.

  • The first is to reduce the role conflict and inspire sharing of status.
  • The other is to yank the rug back.

Wednesday, October 5, 2011

The Mythical Man-Month – Extracts VI

Source: The Mythical Man-Month

Communication in the Large Programming Project

Schedule disaster, functional misfits, and system bugs all arise because the left hand doesn't know what the right hand is doing. As work proceeds, the several teams slowly change the functions, sizes, and speeds of their own programs, and they explicitly or implicitly change their assumptions about the inputs available and the uses to be made of the outputs. How, then, shall teams communicate with one another? In as many ways as possible:
• Informally. Good telephone service and a clear definition of intergroup dependencies will encourage the hundreds of calls upon which common interpretation of written documents depends.
• Meetings. Regular project meetings, with one team after another giving technical briefings, are invaluable. Hundreds of minor misunderstandings get smoked out this way.
• Workbook. A formal project workbook must be started at the beginning. This deserves a section by itself.

The Project Workbook

What. The project workbook is not so much a separate document as it is a structure imposed on the documents that the project will be producing anyway.All the documents of the project need to be part of this structure.This includes objectives, external specifications, interface specifications, technical standards, internal specifications, and administrative memoranda.

Why. Technical prose is almost immortal. The early design of the project workbook ensures that the documentation structure itself is crafted, not haphazard. Moreover, the establishment of a structure molds later writing into segments that fit into that structure.The second reason for the project workbook is control of the distribution of information. The problem is not to restrict information, but to ensure that relevant information gets to all the people who need it.

Organization in the Large Programming Project

If there are n workers on a project, there are (n2-n)/2 interfaces across which there may be communication, and there are potentially almost 2" teams within which coordination must occur. The purpose of organization is to reduce the amount of communication and coordination necessary; hence organization is a radical attack on the communication problems treated above.

The means by which communication is obviated are division of labor and specialization of function. The tree-like structure of organizations reflects the diminishing need for detailed communication when division and specialization of labor are applied.

In fact, a tree organization really arises as a structure of authority and responsibility. The principle that no man can serve two masters dictates that the authority structure be tree-like. But the communication structure is not so restricted, and the tree is a barely passable approximation to the communication structure, which is a network. The inadequacies of the tree approximation give rise to staff groups, task forces, committees, and even the matrix-type organization used in many engineering laboratories.

Let us consider a tree-like programming organization, and examine the essentials which any subtree must have in order to be effective. They are:
1. a mission
2. a producer
3. a technical director or architect
4. a schedule
5. a division of labor
6. interface definitions among the parts

All of this is obvious and conventional except the distinction between the producer and the technical director. Let us first consider the two roles, then their relationship.

What is the role of the producer?

He assembles the team, divides the work, and establishes the schedule. He acquires and keeps on acquiring the necessary resources. This means that a major part of his role is communication outside the team, upwards and sideways. He establishes the pattern of communication and reporting within the team. Finally, he ensures that the schedule is met, shifting resources and organization to respond to changing circumstances.

How about the technical director?

He conceives of the design to be built, identifies its subparts, specifies how it will look from outside, and sketches its internal structure. He provides unity and conceptual integrity to the whole design; thus he serves as a limit on system complexity. As individual technical problems arise, he invents solutions for them or shifts the system design as required. His communications are chiefly within the team. His work is almost completely technical.

Now it is clear that the talents required for these two roles are quite different. Talents come in many different combinations; and the particular combination embodied in the producer and the director must govern the relationship between them. Organizations must be designed around the people available; not people fitted into pure-theory organizations.

Three relationships are possible, and all three are found in successful practice, and they are:

  • The producer and the technical director may be the same man.
  • The producer may be boss, the director his right-hand man.
  • The director may be boss, and the producer his right-hand man.