Monthly Archives: 12月 2011

Mathematical Creation

By Henri Poincaré

The genesis of mathematical creation is a problem which should intensely interest the psychologist. It is the activity in which the human mind seems to take least from the outside world, in which it acts or seems to act only of itself and on itself, so that in studying the procedure of geometric thought we may hope to reach what is most essential in man’s mind…

A first fact should surprise us, or rather would surprise us if we were not so used to it. How does it happen there are people who do not understand mathematics? If mathematics invokes only the rules of logic, such as are accepted by all normal minds; if its evidence is based on principles common to all men, and that none could deny without being mad, how does it come about that so many persons are here refractory?

That not every one can invent is nowise mysterious. That not every one can retain a demonstration once learned may also pass. But that not every one can understand mathematical reasoning when explained appears very surprising when we think of it. And yet those who can follow this reasoning only with difficulty are in the majority; that is undeniable, and will surely not be gainsaid by the experience of secondary-school teachers.

And further: how is error possible in mathematics? A sane mind should not be guilty of a logical fallacy, and yet there are very fine minds who do not trip in brief reasoning such as occurs in the ordinary doings of life, and who are incapable of following or repeating without error the mathematical demonstrations which are longer, but which after all are only an accumulation of brief reasoning wholly analogous to those they make so easily. Need we add that mathematicians themselves are not infallible?…

As for myself, I must confess, I am absolutely incapable even of adding without mistakes… My memory is not bad, but it would be insufficient to make me a good chess-player. Why then does it not fail me in a difficult piece of mathematical reasoning where most chess-players would lose themselves? Evidently because it is guided by the general march of the reasoning. A mathematical demonstration is not a simple juxtaposition of syllogisms, it is syllogisms placed in a certain order, and the order in which these elements are placed is much more important than the elements themselves. If I have the feeling, the intuition, so to speak, of this order, so as to perceive at a glance the reasoning as a whole, I need no longer fear lest I forget one of the elements, for each of them will take its allotted place in the array, and that without any effort of memory on my part.

We know that this feeling, this intuition of mathematical order, that makes us divine hidden harmonies and relations, cannot be possessed by every one. Some will not have either this delicate feeling so difficult to define, or a strength of memory and attention beyond the ordinary, and then they will be absolutely incapable of understanding higher mathematics. Such are the majority. Others will have this feeling only in a slight degree, but they will be gifted with an uncommon memory and a great power of attention. They will learn by heart the details one after another; they can understand mathematics and sometimes make applications, but they cannot create. Others, finally, will possess in a less or greater degree the special intuition referred to, and then not only can they understand mathematics even if their memory is nothing extraordinary, but they may become creators and try to invent with more or less success according as this intuition is more or less developed in them.

In fact, what is mathematical creation? It does not consist in making new combinations with mathematical entities already known. Anyone could do that, but the combinations so made would be infinite in number and most of them absolutely without interest. To create consists precisely in not making useless combinations and in making those which are useful and which are only a small minority. Invention is discernment, choice.

It is time to penetrate deeper and to see what goes on in the very soul of the mathematician. For this, I believe, I can do best by recalling memories of my own. But I shall limit myself to telling how I wrote my first memoir on Fuchsian functions. I beg the reader’s pardon; I am about to use some technical expressions, but they need not frighten him, for he is not obliged to understand them. I shall say, for example, that I have found the demonstration of such a theorem under such circumstances. This theorem will have a barbarous name, unfamiliar to many, but that is unimportant; what is of interest for the psychologist is not the theorem but the circumstances.

For fifteen days I strove to prove that there could not be any functions like those I have since called Fuchsian functions. I was then very ignorant; every day I seated myself at my work table, stayed an hour or two, tried a great number of combinations and reached no results. One evening, contrary to my custom, I drank black coffee and could not sleep. Ideas rose in crowds; I felt them collide until pairs interlocked, so to speak, making a stable combination. By the next morning I had established the existence of a class of Fuchsian functions, those which come from the hypergeometric series; I had only to write out the results, which took but a few hours.

Then I wanted to represent these functions by the quotient of two series; this idea was perfectly conscious and deliberate, the analogy with elliptic functions guided me. I asked myself what properties these series must have if they existed, and I succeeded without difficulty in forming the series I have called theta-Fuchsian.

Just at this time I left Caen, where I was then living, to go on a geologic excursion under the auspices of the school of mines. The changes of travel made me forget my mathematical work. Having reached Coutances, we entered an omnibus to go some place or other. At the moment when I put my foot on the step the idea came to me, without anything in my former thoughts seeming to have paved the way for it, that the transformations I had used to define the Fuchsian functions were identical with those of non-Euclidean geometry. I did not verify the idea; I should not have had time, as, upon taking my seat in the omnibus, I went on with a conversation already commenced, but I felt a perfect certainty. On my return to Caen, for conscience’s sake I verified the result at my leisure.

Then I turned my attention to the study of some arithmetical questions apparently without much success and without a suspicion of any connection with my preceding researches. Disgusted with my failure, I went to spend a few days at the seaside, and thought of something else. One morning, walking on the bluff, the idea came to me, with just the same characteristics of brevity, suddenness and immediate certainty that the arithmetic transformations of indeterminate ternary quadratic forms were identical with those of non-Euclidean geometry.

Returned to Caen, I meditated on this result and deduced the consequences. The example of quadratic forms showed me that there were Fuchsian groups other than those corresponding to the hypergeometric series; I saw that I could apply to them the theory of theta-Fuchsian series and that consequently there existed Fuchsian functions other than those from the hypergeometric series, the ones I then knew. Naturally I set myself to form all these functions. I made a systematic attack upon them and carried all the outworks, one after another. There was one, however, that still held out, whose fall would involve that of the whole place. But all my efforts only served at first the better to show me the difficulty, which indeed was something. All this work was perfectly conscious.

Thereupon I left for Mont-Valérien, where I was to go through my military service; so I was very differently occupied. One day, going along the street, the solution of the difficulty which had stopped me suddenly appeared to me. I did not try to go deep into it immediately, and only after my service did I again take up the question. I had all the elements and had only to arrange them and put them together. So I wrote out my final memoir at a single stroke and without difficulty.

I shall limit myself to this single example; it is useless to multiply them…

Most striking at first is this appearance of sudden illumination, a manifest sign of long, unconscious prior work. The role of this unconscious work in mathematical invention appears to me incontestable, and traces of it would be found in other cases where it is less evident. Often when one works at a hard question, nothing good is accomplished at the first attack. Then one takes a rest, longer or shorter, and sits down anew to the work. During the first half-hour, as before, nothing is found, and then all of a sudden the decisive idea presents itself to the mind…

There is another remark to be made about the conditions of this unconscious work; it is possible, and of a certainty it is only fruitful, if it is on the one hand preceded and on the other hand followed by a period of conscious work. These sudden inspirations (and the examples already cited prove this) never happen except after some days of voluntary effort which has appeared absolutely fruitless and whence nothing good seems to have come, where the way taken seems totally astray. These efforts then have not been as sterile as one thinks; they have set agoing the unconscious machine and without them it would not have moved and would have produced nothing…

Such are the realities; now for the thoughts they force upon us. The unconscious, or, as we say, the subliminal self plays an important role in mathematical creation; this follows from what we have said. But usually the subliminal self is considered as purely automatic. Now we have seen that mathematical work is not simply mechanical, that it could not be done by a machine, however perfect. It is not merely a question of applying rules, of making the most combinations possible according to certain fixed laws. The combinations so obtained would be exceedingly numerous, useless and cumbersome. The true work of the inventor consists in choosing among these combinations so as to eliminate the useless ones or rather to avoid the trouble of making them, and the rules which must guide this choice are extremely fine and delicate. It is almost impossible to state them precisely; they are felt rather than formulated. Under these conditions, how imagine a sieve capable of applying them mechanically?

A first hypothesis now presents itself; the subliminal self is in no way inferior to the conscious self; it is not purely automatic; it is capable of discernment; it has tact, delicacy; it knows how to choose, to divine. What do I say? It knows better how to divine than the conscious self, since it succeeds where that has failed. In a word, is not the subliminal self superior to the conscious self? You recognize the full importance of this question…

Is this affirmative answer forced upon us by the facts I have just given? I confess that, for my part, I should hate to accept it. Re-examine the facts then and see if they are not compatible with another explanation.

It is certain that the combinations which present themselves to the mind in a sort of sudden illumination, after an unconscious working somewhat prolonged, are generally useful and fertile combinations, which seem the result of a first impression. Does it follow that the subliminal self, having divined by a delicate intuition that these combinations would be useful, has formed only these, or has it rather formed many others which were lacking in interest and have remained unconscious?

In this second way of looking at it, all the combinations would be formed in consequence of the automatism of the subliminal self, but only the interesting ones would break into the domain of consciousness. And this is still very mysterious. What is the cause that, among the thousand products of our unconscious activity, some are called to pass the threshold, while others remain below? Is it a simple chance which confers this privilege? Evidently not; among all the stimuli of our senses, for example, only the most intense fix our attention, unless it has been drawn to them by other causes. More generally the privileged unconscious phenomena, those susceptible of becoming conscious, are those which, directly or indirectly, affect most profoundly our emotional sensibility.

It may be surprising to see emotional sensibility invoked à propos of mathematical demonstrations which, it would seem, can interest only the intellect. This would be to forget the feeling of mathematical beauty, of the harmony of numbers and forms, of geometric elegance. This is a true esthetic feeling that all real mathematicians know, and surely it belongs to emotional sensibility.

Now, what are the mathematic entities to which we attribute this character of beauty and elegance, and which are capable of developing in us a sort of esthetic emotion? They are those whose elements are harmoniously disposed so that the mind without effort can embrace their totality while realizing the details. This harmony is at once a satisfaction of our esthetic needs and an aid to the mind, sustaining and guiding. And at the same time, in putting under our eyes a well-ordered whole, it makes us foresee a mathematical law… Thus it is this special esthetic sensibility which plays the role of the delicate sieve of which I spoke, and that sufficiently explains why the one lacking it will never be a real creator.

Yet all the difficulties have not disappeared. The conscious self is narrowly limited, and as for the subliminal self we know not its limitations, and this is why we are not too reluctant in supposing that it has been able in a short time to make more different combinations than the whole life of a conscious being could encompass. Yet these limitations exist. Is it likely that it is able to form all the possible combinations, whose number would frighten the imagination? Nevertheless that would seem necessary, because if it produces only a small part of these combinations, and if it makes them at random, there would be small chance that the good, the one we should choose, would be found among them.

Perhaps we ought to seek the explanation in that preliminary period of conscious work which always precedes all fruitful unconscious labor. Permit me a rough comparison. Figure the future elements of our combinations as something like the hooked atoms of Epicurus. During the complete repose of the mind, these atoms are motionless, they are, so to speak, hooked to the wall…

On the other hand, during a period of apparent rest and unconscious work, certain of them are detached from the wall and put in motion. They flash in every direction through the space (I was about to say the room) where they are enclosed, as would, for example, a swarm of gnats or, if you prefer a more learned comparison, like the molecules of gas in the kinematic theory of gases. Then their mutual impacts may produce new combinations.

What is the role of the preliminary conscious work? It is evidently to mobilize certain of these atoms, to unhook them from the wall and put them in swing. We think we have done no good, because we have moved these elements a thousand different ways in seeking to assemble them, and have found no satisfactory aggregate. But, after this shaking up imposed upon them by our will, these atoms do not return to their primitive rest. They freely continue their dance.

Now, our will did not choose them at random; it pursued a perfectly determined aim. The mobilized atoms are therefore not any atoms whatsoever; they are those from which we might reasonably expect the desired solution. Then the mobilized atoms undergo impacts which make them enter into combinations among themselves or with other atoms at rest which they struck against in their course. Again I beg pardon, my comparison is very rough, but I scarcely know how otherwise to make my thought understood.

However it may be, the only combinations that have a chance of forming are those where at least one of the elements is one of those atoms freely chosen by our will. Now, it is evidently among these that is found what I called the good combination. Perhaps this is a way of lessening the paradoxical in the original hypothesis…

I shall make a last remark: when above I made certain personal observations, I spoke of a night of excitement when I worked in spite of myself. Such cases are frequent, and it is not necessary that the abnormal cerebral activity be caused by a physical excitant as in that I mentioned. It seems, in such cases, that one is present at his own unconscious work, made partially perceptible to the over-excited consciousness, yet without having changed its nature. Then we vaguely comprehend what distinguishes the two mechanisms or, if you wish, the working methods of the two egos. And the psychologic observations I have been able thus to make seem to me to confirm in their general outlines the views I have given.

Surely they have need of [confirmation], for they are and remain in spite of all very hypothetical: the interest of the questions is so great that I do not repent of having submitted them to the reader.

hackme: Deconstructing an ELF File

dummy library, disassembly

————————————————————————————————————————

来源:http://manoharvanga.com/hackme/

A friend recently asked me to find the password for a little hard-to-hack program he had written and I agreed to it. The short journey of a few hours that led me to its password were extremely interesting and this article describes the process as well as some of the new techniques learnt along the way.

Few minutes after accepting his challenge, I received a binary called “hackme” in an E-mail and I got started! Those interested in giving it a shot can download the binary file and get back to this article later. Do let me know if you find anything interesting along the way that I did not think of or missed! Comments can be sent to manohar dot vanga at gmail dot com with the title [hackme]. UPDATE: You can post comments to the Hacker News discussion.

Test Run

I ran the binary and tried a couple of random passwords. As expected, they failed, providing me with an extremely helpful message:

$ ./hackme
Password, please? password
Oops..

Interestingly, running the binary under GDB gave a specially crafted welcome message:

$ $ gdb ./hackme 
Reading symbols from /tmp/hack/hackme...(no
debugging symbols found)...done.
(gdb) r
Starting program: ./hackme

Fuck off! no debuggers!
Program exited with code 0364.
(gdb) 

Same with ptrace:

$ strace ./hackme 
execve("./hackme", ["./hackme"], [/* 41 vars */]) = 0
brk(0)                                  = 0x9016000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such
file or directory)
... snip ...
ptrace(PTRACE_TRACEME, 0, 0, 0)         = -1 EPERM (Operation
not permitted)
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 3), ...})
= 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb783e000
write(1, "Fuck off! no debuggers!\n", 24Fuck off! no debuggers!
) = 24
_exit(2543604)                          = ?

The Obvious Stuff

Even though the probability of a password being visible in plain sight was near zero, I decided to give it a shot anyway.

First, I checked if the binary was stripped or not:

$ file hackme
hackme: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically
linked (uses shared libs), for GNU/Linux 2.6.27, stripped

It was stripped. Dead end there. GDB would not be much help with a stripped binary in terms of deconstructing the logic. I decided to try looking for a literal string comparison with the password within the binary just in case:

$ strings hackme
/lib/ld-linux.so.2
libdl.so.2
__gmon_start__
_Jv_RegisterClasses
dlopen
dlsym
libc.so.6
_IO_stdin_used
__libc_start_main
random
GLIBC_2.1
GLIBC_2.0
PTRh 
QVhE
[^Ph
[^_]
8%':!06!
%!'460
&64;3
%'<;!3
UWVS
[^_]
Fuck off! no debuggers!
Password, please? 
Congratulations!
Oops..

Just in case, I try all the strings as passwords but they all fail. Not too surprising. The output however gives me the message that gets printed on success; “Congratulations!”. It also seems to be containing the string “libc.so.6”. Fishy. A quick ltrace quickly explains what the binary is doing:

$ ltrace ./hackme 
__libc_start_main(0x8048645, 1, 0xbfb48a04, 0x80486b0, 0x8048720
<unfinished ...>
dlopen("/lib/libc.so.6", 2)
= 0xb7757ae0
dlsym(0xb7757ae0, "ptrace")
= 0x00eddf40
dlsym(0xb7757ae0, "scanf")
= 0x00e621a0
dlsym(0xb7757ae0, "printf")
= 0x00e5baa0
Fuck off! no debuggers!
+++ exited (status 244) +++

While this gives us the same welcoming message, we can see what is happening here. The libc shared library is being opened dynamically and the addresses of ptrace, scanf and printf are being retreived with dlsym! Sneaky trick!

More irritatingly however, the strings output shows that the binary is using the random() function. However, since it is a reproducible program, that is the password works every time, the call to random is probably not being seeded. We will worry about this later.

The strings output also explains how the binary is detecting the debugging environment. Calling ptrace while running inside a ptraced environment (eg. strace, ltrace or gdb) returns -1.

Getting over this debugger hurdle however is quite easy using the LD_PRELOAD environment variable. The LD_PRELOAD environment variable can contain a list of custom shared objects which are then loaded prior to all others when running an executable. It is an easy route to blocking a process from calling unwanted functions. I quickly wrote a quick dummy function in a new file:

/* fake ptrace() */
#include <stdio.h>

long ptrace(int x, int y, int z)
{
	printf("B-)\n");
	return 0;
}

…and compiled it:

gcc -shared -fPIC -o fake.so fake.c

Now running under strace with the LD_PRELOAD variable set to our fake shared object gives us the full scoop!

$ strace -E LD_PRELOAD=./fake.so ./hackme
execve("./hackme", ["./hackme"], [/* 24 vars */]) = 0
brk(0)                                  = 0x9727000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such
file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb78a6000
open("./fake", O_RDONLY)                = 3
read(3,
"\177ELF\1\1\1\3\3\1\240\3004"...,
512) = 512
... snip ...
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb78a1000
write(1, "Password, please? ", 18Password, please? )      = 18
read(0, password
"password\n", 1024)             = 9
write(1, "Oops..\n", 7Oops..
)                 = 7
exit_group(7)                           = ?

Looks like the password buffer is 1024 bytes long. I could try overflowing that but coupled with stack randomization (which can be turned off if I remember correctly), it would be hard to do on a lazy Friday. More importantly, my goal is not the break the program but to get the password!

It is starting to seem like my only option left is to sit and reverse engineer the code for this binary; something I did not want to get in to on a Friday afternoon. A geek challenge however trumps laziness any day of the week so I started with the task of disassembling the binary.

Disassembly

I start with an objdump output (go ahead and open it in a new tab if you want to follow along):

$ objdump -D ./hackme > out.asm

The assembly is a mess as expected of a stripped binary. I quickly need to find the part that pertains to the password encryption logic. From the test run, I know that the logic is somewhere between where it prints the “Password, please?” message and the “Oops..” message. I will start by locating these strings in the assembly output and backtracing to where they are being used. The “Pa” of the “Password, please?” string is 50 followed by 61 in hexadecimal. A quick search locates the string in the assembly output:

$ grep "50 61" objdumpout.txt 
 8048798:	00 50 61             	add    %dl,0x61(%eax)

The address of the string therefore is 0x8048799 (since the first byte needs to be skipped). Searching the file for this address leads me to this code:

 804859d:       68 99 87 04 08          push   $0x8048799
 80485a2:       ff 15 94 99 04 08       call   *0x8049994

Great! It is pushing the address of the string (as a literal) on to the stack and calling an address. I assume that this is the variable storing the address returned by dlsym for printf.

Now I need to find the “Oops..” message. I repeat the same procedure to get to the string and find the code:

 8048633:       68 c1 87 04 08          push   $0x80487c1
 8048638:       ff d0                   call   *%eax

While I am at it, I pick out the “Congratulations!” message as well and find the location. Finally the code looks much more comprehensible:

 # The "Password, please?" message is being printed here
 804859d:	68 99 87 04 08       	push   $0x8048799
 80485a2:	ff 15 94 99 04 08    	call   *0x8049994
 80485a8:	8d 45 84             	lea    -0x7c(%ebp),%eax
 ... snip ...
 8048626:	83 ec 0c             	sub    $0xc,%esp
 # The "Congratulations!" message is being printed here
 8048629:	68 af 87 04 08       	push   $0x80487af
 804862e:	eb 08                	jmp    8048638 <dlopen@plt+0x268>
 8048630:	83 ec 0c             	sub    $0xc,%esp
 # The "Oops.." message is being printed here
 8048633:	68 c1 87 04 08       	push   $0x80487c1
 8048638:	ff d0                	call   *%eax

I quickly annotate the assembly (bottom posting of comments) so I remember what I figured out:

 804859d:	68 99 87 04 08       	push   $0x8048799
 80485a2:	ff 15 94 99 04 08    	call   *0x8049994
 # The "Password, please?" message is being printed here

 80485a8:	8d 45 84             	lea    -0x7c(%ebp),%eax
 # This is probably the address of the password buffer.

 80485ab:	5b                   	pop    %ebx
 80485ac:	5e                   	pop    %esi

 80485ad:	50                   	push   %eax
 80485ae:	68 ac 87 04 08       	push   $0x80487ac
 80485b3:	ff 15 90 99 04 08    	call   *0x8049990
 80485b9:	83 c4 10             	add    $0x10,%esp
 # Push the password buffer and the string "%s" onto the stack and call scanf

 80485bc:	31 c0                	xor    %eax,%eax
 # Clear EAX.

 80485be:	eb 01                	jmp    80485c1 <dlopen@plt+0x1f1>
 80485c0:	40                   	inc    %eax
 80485c1:	80 7c 05 84 00       	cmpb   $0x0,-0x7c(%ebp,%eax,1)
 80485c6:	75 f8                	jne    80485c0 <dlopen@plt+0x1f0>
 # Find the string length of the password we entered. Return value in EAX.

 80485c8:	31 db                	xor    %ebx,%ebx

 80485ca:	83 f8 13             	cmp    $0x13,%eax
 80485cd:	0f 94 c3             	sete   %bl
 # Hmm! If the strlen(buf) != 0x13) BL is set to 1! We have our first hint!

 80485d0:	be 0a 00 00 00       	mov    $0xa,%esi
 # Move integer 10 into ESI. This is the start of a loop that runs 10 times.

 80485d5:	e8 b6 fd ff ff       	call   8048390 <random@plt>
 # Call random(). Return value in EAX

 80485da:	b9 13 00 00 00       	mov    $0x13,%ecx
 80485df:	99                   	cltd   
 80485e0:	f7 f9                	idiv   %ecx
 # Divide the random number in EAX with 19. EAX is quotient, EDX is remainder.

 80485e2:	31 c0                	xor    %eax,%eax
 # Throw away quotient.

 80485e4:	8a 8a 9c 86 04 08    	mov    0x804869c(%edx),%cl
 # Hmm. That address looks like a lookup table of some sort.
 # The operation is basically doing "CL = table[remainder]".
 # Since remainder can't be more that 19, I dump the first 19 bytes of this
 # address:
 #     0xfb, 0x4c, 0x8d, 0x58, 0x0f, 0xd4, 0xe8, 0x94, 0x98, 0xee,
 #     0x6b, 0x18, 0x30, 0xe0, 0x55, 0xc5, 0x28, 0x0e

 80485ea:	0f b6 7c 15 84       	movzbl -0x7c(%ebp,%edx,1),%edi
 # This basically does EDI = password[remainder]

 80485ef:	42                   	inc    %edx
 80485f0:	89 95 74 ff ff ff    	mov    %edx,-0x8c(%ebp)
 # Increment the remainder and store it in another variable

 80485f6:	31 d2                	xor    %edx,%edx
 80485f8:	eb 0c                	jmp    8048606 <dlopen@plt+0x236>
 80485fa:	69 c0 8d 78 01 6d    	imul   $0x6d01788d,%eax,%eax
 8048600:	42                   	inc    %edx
 8048601:	05 39 30 00 00       	add    $0x3039,%eax
 8048606:	3b 95 74 ff ff ff    	cmp    -0x8c(%ebp),%edx
 804860c:	7c ec                	jl     80485fa <dlopen@plt+0x22a>
 # This is a weird loop. It seems to be a pseudorandom generator.
 # The loop runs while a counter is less than the incremented remainder above.
 # Inside, it's doing the following (remember eax was cleared above to 0):
 #     eax = eax * 0x6d01788d //This is a prime number according to Wolfram Alpha
 #     eax += 0x3039 // 12345 in decimal
 # That is an unseeded (or seeded to 0) pseudorandom generator! Nice but
 # pointless as it is unseeded.

 804860e:	31 f8                	xor    %edi,%eax
 # XOR the pseudorandom value above with password[remainder] as stored above

 8048610:	38 c1                	cmp    %al,%cl
 # Compare the lower byte of the XOR'ed result with the lookup table entry stored in CL

 8048612:	b8 00 00 00 00       	mov    $0x0,%eax
 8048617:	0f 45 d8             	cmovne %eax,%ebx
 # If the lower byte of the XOR is not equal to the lookup table entry set EBX=0

 804861a:	4e                   	dec    %esi
 804861b:	75 b8                	jne    80485d5 <dlopen@plt+0x205>
 # Decrement the main loop counter (the one that runs 10 times) and jump
 # if more iterations are left

 804861d:	85 db                	test   %ebx,%ebx
 804861f:	a1 94 99 04 08       	mov    0x8049994,%eax
 8048624:	74 0a                	je     8048630 <dlopen@plt+0x260>
 # At last! Jump to the failure message (past the congratulations) if EBX is 0!
 # EBX should be non-zero in order to print the congratulations message!

 8048626:	83 ec 0c             	sub    $0xc,%esp

 # The "Congratulations!" message is being printed here
 8048629:	68 af 87 04 08       	push   $0x80487af
 804862e:	eb 08                	jmp    8048638 <dlopen@plt+0x268>
 8048630:	83 ec 0c             	sub    $0xc,%esp

 # The "Oops.." message is being printed here
 8048633:	68 c1 87 04 08       	push   $0x80487c1
 8048638:	ff d0                	call   *%eax

Phew! That was not as bad as I expected! Converting that logic to C code that dumps out the password took me a while with testing and the final result looked like the following:

#include <stdio.h>
#include <string.h>

int main()
{
    int i, j, edi;
    char buf[50], ch;
    char out[50];
    unsigned char check;
    int ret = 0, val, len, rem;
    int magic;
    int k;
    unsigned char arr[] = {0x6a, 0xfb, 0x4c, 0x8d, 0x58, 0x0f, 0xd4, 0xe8,
        0x94, 0x98, 0xee, 0x6b, 0x18, 0x30, 0xe0, 0x55, 0xc5, 0x28,
        0x0e};

    for (i = 0; i < 19; i++)
        out[i] = 'x';
        out[i] = '';

    for (i = 10; i > 0; i--) {
        int m2;

        val = random();
        rem = val%19;
        check = arr[rem] & 0xff;
        ch = buf[rem++];

        j = 0;
        magic = 0;
        printf("rem = %d\n", rem);
        while (j < rem) {
        magic *= 1828812941;
        magic += 12345;
        j++;
        }
        m2 = magic;

        magic ^= ch;
        out[rem - 1] = (m2 & 0xff) ^ (check & 0xff));
    }
    printf("Password: %s\n", out);
}

Now for the fun; the output:

$ ./decompiled
rem = 3
rem = 16
rem = 4
rem = 4
rem = 11
rem = 9
rem = 11
rem = 12
rem = 3
rem = 8
Password: xxsaxxxpexYoxxxexxx

The loop in the binary runs only 10 times and it has repeating checks for some offsets of the password. The only characters of the password that matter are the ones NOT marked with an ‘x’ in the output (I make the program set these as it runs).

Now the sweet part! I run the password against the original program:

$ ./hackme 
Password, please? xxsaxxxpexYoxxxexxx
Congratulations!

HA! That was fun!

Conclusions

So what did I learn?

Know Thy Tools

I knew how to get around many of the hurdles I faced from past knowledge and experiences with the various tools I used. The better you know your tools, the more you can think about the real issues at hand (in this case, reversing the program logic).

Test the Waters

I knew I would not find an easy way to reverse this program but I tried all the easy routes anyway. Even though it did not provide me with much information, I gained confidence after having eliminated some of the options. It cleared the way forward.

Know Thy Assembly

The machine instructions were a little hard to decompile and I found myself referencing the Intel manuals from time to time to figure out what was going on. More than the assembly itself though, I really recommend learning the GNU Assembler syntax. I was familiar with the Intel syntax (eg. NASM) but not completely proficient with GAS syntax (AT&T syntax). I found this article and this article very useful in quickly brushing this up.

Some thoughts on the program itself follow

  • Checking only few parts of the password was ineffective although it would not have made life much more difficult if every character was checked. (Note: The original author told me he put the 10 in the main loop for debugging purposes and forgot to change it)
  • The random number was a nice way to scare me a little but in the end, it had to be unseeded to be deterministic and consequently, not very effective. If I had a different version of libc with a different random(), the program would probably have failed with the original password.
  • The actual password was “SesameOpenYourself!”! I came up with a few nonsensical variations that worked as well. eg. “NasaJeeperYouShelby”.

All in all, a good Friday afternoon! Again, comments can be mailed to manohar dot vanga at gmail dot com with a title of [hackme].

Download: all files

Interactive Application Architecture Patterns

 

——————————————————————————————————————————

Clipped on 29-December-2011, 2:33 PM from Interactive Application Architecture Patterns

——————————————————————————————————————————

On August 25, 2007, in Uncategorized, by derekgreer

Introduction

The MVC, MVP, and PAC patterns are each intended to address the needs of interactive applications by separating the concerns assigned to different components within their respective architectures. While similar, each of these patterns differs slightly in their motivations and applicability to various design goals. This article discusses each pattern along with its history and design motivations to encourage the correct understanding and application of these patterns.

In discussing architecture patterns in general, it is helpful to understand that patterns in this class are often motivated by design considerations which were formed within the context of specific development environments. As such, platform specific motivations and the pattern’s implementation details are often incorporated into the formal description of the pattern.For instance, the Model-View-Controller pattern had the primary design motivation of separating presentation from domain concerns. The division between the input and output of the application (which resulted in the concept of the Controller component), was really a byproduct of addressing complexities inherent to the host platform.

Today’s development environments have come a long way in shielding developers from such complexities making divisions between device input and output at the application level unnecessary. In such environments, an application of the Model-View-Controller pattern may result in an approach which adheres to the intent of the pattern while not following its original form, or adheres to its original form without following its original intent.

Within many development environments, the original goals of the Model-View-Controller pattern can be accomplished today by merely separating an application’s Forms and associated Controls from its domain model. The formalizing of a Controller for intercepting user input is unnecessary in platforms which natively provide this functionality. When attempting to follow the original form of the Model-View-Controller pattern within such development environments, the resulting architecture may fall somewhere between a strict implementation of MVC which goes against the grain of the hosting environment and an implementation which assigns different responsibilities to the original components. From this observation it can be deduced that the Model-View-Controller pattern isn’t adequately distilled into pattern language. That is to say, the components prescribed by the MVC pattern are not agnostic of the assumed development environment, and most descriptions do not make this explicit. This often results in a misappropriation of the pattern.

Another suggestion when studying and considering the use of interactive design patterns is to take the whole subject with a grain of salt. Many base patterns, such as those presented in the seminal work Design Patterns – Elements of Reusable Object-Oriented Software by Gamma, etc. al. are well distilled patterns which describe solutions to common problems in a implementation-agnostic way. Because of the nature of these patterns, scores of competing constructs aren’t generally found purporting to address the same concern. However, when entering the realm of compound patterns such as interactive application patterns, models, styles, etc., the study of such constructs can feel a bit like watching a documentary of the history of airplanes.

1

It’s best to think of architecture patterns as being as much in the realm of art as science. Interactive architecture patterns aren’t the computer science equivalent of Newton’s Law of Gravity. They merely represent our ever evolving attempt to apply the best approach for application development. Finally, when considering use of these patterns remember that their application should be considered for their applicability to the problem, not so one can proudly proclaim: “I use the such-and-such pattern”. Use of design patterns should be the result of having started with a problem for which an existing pattern was known or found to be applicable, not the result of starting with a pattern for which a problem was sought out or invented in order to use the pattern.

The Model–View-Controller Pattern

Overview

The Model-View-Controller pattern is a methodology for separating the concerns of an application’s domain, presentation, and user input into specialized components.

Origins and Motivation

The MVC pattern was originally conceived in 1978-79 by Trygve Reenskaug and had the primary goal of providing an interface for users to manipulate multiple views of data as if working with real world entities. The pattern was first referred to as the Thing-Model-View-Editor before Reenskaug and his colleges settled on the name Model-View-Controller (1). A modified version of Dr. Reenskaug’s design was later implemented as part of the Xerox PARC Smalltalk-80 class library. A description of this implementation can be found in the work: Applications Programming in Smalltalk-80(TM): How to use Model-View-Controller (MVC).

Structure

The following diagram depicts the structure of the Model-View-Controller pattern:

2

Note: While some descriptions of the MVC pattern show an indirect association from the View to the Controller, the original implementation of MVC in Smalltalk-80 coupled View to Controller, and vice-versa (2).

Components

The Model refers to the data and business functionality of the application. This is often represented by a Domain Model where objects are used to model real world entities and processes by representing their properties and behavior. The View is the visual representation of the Model and is comprised of the screens and widgets used within an application. The Controller is a component which responds to user input such as data entry and commands issued from a keyboard or mouse. Its responsibility is to act as a bridge between the human and the application, allowing the user to interact with the screen and data.

Collaborations

Within the MVC pattern, a Model-View-Controller triad exists for each object intended to be manipulated by a user. The Model represents the state, structure, and behavior of the data being viewed and manipulated by the user. The Model contains no direct link to the View or Controller, and may be modified by the View, Controller, or other objects with the system. When notification to the View and Controller are necessary, the Model uses the Observer Pattern to send a message notifying observing objects that its data has changed. The View and Controller components work together to allow the user to view and interact with the Model. Each View is associated with a single Controller, and each Controller is associated with a single View. Both the View and Controller components maintain a direct link to the Model.

Note: Within the Smalltalk-80 implementation, both the View and Controller maintained a direct link to one another, though the link from the View to the Controller was largely a byproduct of its implementation rather than an inherent part of the MVC pattern. The link was not maintained to delegate user input intercepted by the View to the Controller as is the case with the Dolphin Smalltalk Model-View-Presenter pattern to be discussed later, but was rather used by the View to initialize the controller with an instance of itself, and by a top level Controller to locate the active Controller within a View hierarchy.

The View’s responsibility can be seen as primarily dealing with output while the Controller’s responsibility can be seen as primarily dealing with input. It is the shared responsibility of both the View and the Controller to interact with the Model. The Controller interacts with the Model as the result of responding to user input, while the View interacts with the Model as the result of updates to itself. Both may access and modify data within the Model as needed. As data is entered by the user, the Controller intercepts the user’s input and responds appropriately. Some user actions will result in interaction with the Model, such as changing data or invoking methods, while other user actions may result in visual changes to the View, such as the collapsing of menus, the highlighting of scrollbars, etc.

MVC Misconceptions

One common misconception about the relationship between the MVC components is that the purpose of the Controller is to separate the View from the Model. While the MVC pattern does decouple the application’s domain layer from presentation concerns, this is achieved through the Observer Pattern, not through the Controller. The Controller was conceived as a mediator between the end user and the application, not between the View and the Model.

Pattern Variations and Derivatives

The classic Model-View-Controller pattern is largely no longer used today in its original form, though it has given rise to a number of variations adapted to newer development platforms. The next section will discuss a derivative of the pattern adapted for use with Web development.

The Model-View-Controller Pattern for Web Applications

Overview

Since the advent of the Web, an analog to the original Model-View-Controller pattern has emerged for use with Web applications. Similar to the original pattern, the Web-based MVC pattern aids in separating the concerns of an application’s domain, client-side presentation, and server side input processing into specialized components.

Origins

The Web-based MVC pattern emerged somewhat naturally as object-oriented design was applied to the stateless nature of the HTTP protocol and HTML presentation. Web applications provide the ability to serve up dynamic content to Web clients by processing inbound HTTP requests through server-side components.

As various approaches to Web development emerged, the need for processing and routing inbound requests generally led to to the creation of infrastructure code which served the same logical purpose as the original Smalltalk-80 controllers … directing the application in response to signals from an end-user.

The text-based nature of HTML also led to template-based approaches to separating content from application logic, especially for localized applications. As these techniques were applied in the context of object-oriented applications, a pattern emerged similar to that of the original MVC pattern. The pattern eventually became associated with Java’s “Model 2″ architecture.

From the mid to late 1990′s, Web applications were predominately developed using the Common Gateway Interface (CGI) standard. CGI applications can take the form of compiled or interpreted code and are spawned as separate processes by a Web server to process inbound HTTP requests. In 1997, Sun Microsystems published the Java Servlet 1.0 specification to improve upon CGI-based applications by processing HTTP requests as separate threads within a hosted Java Virtual Machine (JVM). In 1999, Sun further built upon their framework by introducing the Java Server Pages (JSP) 1.0 specification. Similar in concept to Microsoft’s Active Server Pages (ASP) introduced in December of 1996, Java Server Pages provided an abstraction to the creation of Servlets by enabling developers to create specialized HTML templates embedded with Java “scriptlets” which were compiled to Java Servlets when accessed.

The first draft of the JSP specification included guidance for two approaches to using the new technology. The first was effectively a Model-View separation where requests were routed directly to JSPs which would in turn interact with the application’s model (“JavaBeans” in Java parlance). The second approach, recommended for more complex applications, was effectively a Model-View-Controller separation where requests were routed to Java Servlets which interacted with the model and subsequently transferred control to a JSP for rendering the view back to the browser. An updated draft of the JSP specification referred to these approaches as Model 1 and Model 2 respectively. While no association with the Smalltalk-80 MVC pattern was made within the specification, the similarity was noted in an article appearing in Java World magazine on December of the same year, stating that the Model 2 architecture could be seen as a “server-side implementation of the popular Model-View-Controller (MVC) design pattern” (17). While introduced by Sun as the Model 2 architecture, the credit for the mainstream adoption of a Web-based Model-View-Controller pattern rightly belongs to Craig R. McClanahan for his creation of the Struts framework and its donation to the Apache Foundation in June of 2000. Struts was introduced as an MVC framework and became widely adopted in the Java development community upon its release as well as the catalyst for the development of a plethora of frameworks in the following years.

Structure

While no canonical structure exists, the following diagram is a depiction of how the MVC pattern is often adapted for Web development:

3

Components

With Web applications, a Front Controller is often introduced to handle common infrastructure concerns as well as dispatching requests to individual Controllers. This might take the form of a Servlet in Java-based applications, or an IHttpHandler in ASP.Net-based applications. Examples of common concerns handled by a Front Controller might include security, session state management, or dependency injection resolution of the handling Controller. As with the Smalltalk-80 MVC pattern, the Model encapsulates the data and business functionality of the application and is typically represented by a Domain Model. In Web applications, the View is the content (generally HTML and associated client-side script) returned to the Web client. Depending on the implementation, Views may be text-based templates which are rendered by a view processor, or they may be objects compiled from templates which encapsulate the content to be rendered. Also similar to the original Smalltalk-80 MVC pattern, the Controller is a component which responds to user input. What differs is that rather than receiving signals directly from hardware devices such as the keyboard, mouse, etc., Web-based MVC Controllers process delegated HTTP requests (or information derived from the request depending upon the specific implementation).

Collaborations

Upon receiving an HTTP request, the Front Controller executes any common behavior and then uses information derived from the request to locate the concerned Controller. After a Controller is located, the request is delegated for further handling. Once the Controller receives the specific request, the appropriate operations are performed upon the Model and control is transferred to the View. Due to the fact that Web applications are stateless, Views are rendered anew upon each request. As such, the Observer Pattern is not used in the process of updating the View. To render the View with the appropriate state, the Controller makes the required state available in the form of a Model, a Presentation Model, or some more rudimentary form such as a bag of name/value pairs. Depending upon the implementation, the View then renders the output stream or is parsed by a separate processor to render the output stream based upon the view state made available by the Controller. In the following section, another derivative of the Model-View-Controller pattern will be discussed which largely resulted as an adaptation for use with the Microsoft Windows development platform. This pattern is known as the Model-View-Presenter pattern.

The Model-View-Presenter Pattern

The Model-View-Presenter pattern is a variation on the Model-View-Controller pattern, and similarly separates the concerns of an application’s domain, presentation, and user input into specialized components. The definition and distinctive characteristics of this pattern are not easily summarized due to the fact that there are several patterns commonly accepted under the name “Model-View-Presenter” which do not share the same distinctive qualities over their MVC predecessor. For this reason, this article will discuss the original Model-View-Presenter pattern along with some of its more popular variations and derivatives.

The Taligent Model-View-Presenter Pattern

Overview

The Taligent Model-View-Presenter pattern separates the application concerns of data, data specification, data manipulation, application coordination, user interaction, and presentation into specialized components (whew, that’s a mouthful).

Origins and Motivation

The MVP pattern was based on the Taligent programming model, which itself was influenced by the original Smalltalk-80 MVC pattern. The pattern was first formally described by Mike Potel in 1996 while working for Taligent, Inc.. Taligent was started by Apple Computer, Inc. as a joint venture with IBM (and later joined by Hewlett Packard) before becoming the wholly owned subsidiary of IBM in late 1995. Many of the elements of the original MVP pattern began taking form at Apple under the management of Larry Tesler, who formerly worked at Xerox PARC where he was one of the contributors of the design and implementation of Smalltalk. While the main elements of the pattern were already being utilized at Taligent between 1992 and 1994, it wasn’t until after Taligent, Inc. was purchased by IBM in 1995 that Mike Potel first suggested the name “Model-View-Presenter” to describe the architecture found within the Taligent programming model. Dr. Potel credits Arn Schaeffer, Dave Anderson, and David Goldsmith as leading contributors to the Taligent programming model from which the MVP pattern was derived (3).

Structure

The following diagram depicts the structure of the Taligent Model-View-Presenter pattern:

 

Com4ponents

The Model refers to the data and business functionality of the application. Selections are components which specify what portion of the data within the Model is to be operated upon. Examples would be selections which define rows, columns, or individual elements which meet specific criteria. Commands are components which define the operations which can be performed on the data. Examples might be deleting, printing, or saving data within the Model. The View is the visual representation of the Model and is comprised of the screens and widgets used within an application. Interactors are components which address how user events are mapped onto operations performed on the Model, such as mouse movements, keyboard input, and the selection of checkboxes or menu items. The Presenter is a component which orchestrates the overall interaction of the other components within the application. Its roles include the creation of the appropriate Models, Selections, Commands, Views, and Interactors, and directing the workflow within the application.

Collaborations

The most notable collaborative differences between the Taligent Model-View-Presenter pattern and the Model-View-Controller pattern are found within the Presenters and Interactors. The Presenter acts as an overall manager for a particular subsystem within an application. It maintains the lifecycle and relationships between the Views, Interactors, Commands, Selections, and Model. The responsibility for intercepting user events is governed by Interactors; therefore Presenters are not needed for each widget on a given View as were Smalltalk-80 Controllers. There is generally a single Presenter per View, though in some cases a Presenter may manage multiple logically related Views. Interactors are somewhat analogous to Smalltalk-80 Controllers. They are the components which respond to user events and in turn call the appropriate Commands and Selections of the Model.

The Dolphin Smalltalk Model-View-Presenter Pattern

Overview

The Dolphin Smalltalk Model-View-Presenter pattern separates an application’s concerns of domain, presentation, and presentation logic into the specialized components of Model, View, and Presenter. The Dolphin Smalltalk team simplified the Taligent MVP pattern by eliminating Interactors, Commands, and Selections from the pattern’s formal description. This in turn simplified the role of the Presenter, changing it from a subsystem controller to a component which mediated updates to the Model on behalf of the View.

Origins and Motivation

The Dolphin Smalltalk Model-View-Presenter pattern was adapted from the Taligent Model-View-Presenter pattern to address flexibility issues the Dolphin development team was having in its approach to view/domain separation. One of the team’s early considerations included a variation on the MVC pattern used by ParcPlace Systems’ VisualWorks. While the Dolphin team considered the VisualWorks MVC design initially, they later became disenchanted with its prescribed Application Model whose complexity at times tempted developers to allow the model to access the view directly. They also found that the MVC concept of a Controller, whose primary purpose was to respond to user events, didn’t mesh well with more current development platforms whose native widgets handled user events directly. After encountering the Taligent MVP pattern, the Dolphin team concluded it was more applicable for achieving their design goals. While they saw benefits in the Taligent MVP pattern, they mistakenly believed that Taligent derived their pattern from the VisualWorks’ MVC implementation and had eliminated the use of an Application Model by moving presentation logic concerns from the Model to the Presenter. They described this as “Twisting the Triad”, though this does not accurately portray the differences between the Taligent MVP pattern and the original Smalltalk-80 MVC pattern. Due to this misunderstanding, they viewed the Presenter component as being a replacement of the Application Model within VisualWorks’ MVC rather than an evolution of the Controller component within the Smalltalk-80 MVC. The resulting pattern implemented by the Dolphin Smalltalk team was void of most of the components which gave the original MVP its distinctiveness from MVC, though it introduced distinctive qualities of its own.

Structure

The following diagram depicts the structure of the Dolphin Smalltalk Model-View-Presenter pattern:

5

Components

The Model refers to the data and business functionality of the application. The View is the visual representation of the Model and is comprised of the screens and widgets used within an application. The Presenter is a component which contains the presentation logic which interacts with the Model.

Collaborations

Within the Dolphin MVP pattern, Views intercept the initial user events generated by the operating system. This choice was primarily the result of development on the Microsoft Windows operating system whose native widgets already handled most controller functionality. In a few cases the View responded to user events by updating the Model directly, but in most cases user events were delegated to the Presenter. Implied by the Dolphin Smalltalk description is that Views only delegated events when updates to the Model were required, thus leaving all other presentation logic within the View. As with the Taligent MVP pattern, there is usually a single Presenter which handles updates to the Model for a specific View. As with the Model-View-Controller pattern, the View is notified of any changes to the Model using the Observer Pattern and responds by updating the relevant portions of the screen.

Dolphin Smalltalk MVP vs. Smalltalk-80 MVC

On the surface, the differences between the Dolphin Smalltalk MVP pattern and the Smalltalk-80 MVC pattern are difficult to discern. Both of the patterns contain a triad. Both of the patterns contain a Model and View which are virtually identical in function. Both the Smalltalk-80 Controller and the Dolphin Smalltalk Presenter are involved in updating the Model. Both of the patterns use the Observer Pattern to update the View when changes occur to the Model. With all these similarities, it is clear why so much confusion surrounds understanding how the Model-View-Presenter pattern sets itself apart from the Model-View-Controller pattern. The key is in understanding the primary functions which Presenters and Controllers play within their respective triads. Within the original Model-View-Controller pattern, the primary purpose of the Controller was to intercept user input. The Controller’s role of updating the Model was largely a byproduct of this function rather than an inherent part of its purpose. Conversely, within the Dolphin Smalltalk Model-View-Presenter pattern, the primary purpose of the Presenter was to update the Model. The Presenter’s role of intercepting events delegated by the View was largely a byproduct of this function rather than an inherent part of its purpose. Part of the original idea leading to the development of the MVC pattern was a separation between the representation of a user’s mental idea of the data (i.e. the Model), and the logic which allowed the user to interact with that representation (i.e. the Editor). This was considered Model/Editor separation (4). Because the tasks involved in displaying data on the screen were technically very different from the tasks involved in interpreting the user’s input from devices such as the keyboard and the mouse, the combination of these tasks into a single object resulted in unnecessary complexity. Therefore, the concerns of input and output were separated into Views and Controllers. Because Controllers were assigned the input responsibility of the Editor, it naturally followed that they took on the responsibility of updating the Model when input was received from the user. Within the Dolphin Smalltalk MVP pattern, the role of intercepting the user’s input was moved to the View. This effectively eliminated the original need for Controllers or Interactors altogether. While the original idea of the Presenter was seen by the Taligent team as a Controller elevated to an application level, the Dolphin team mistakenly considered it a replacement of the VisualWorks’ Application Model and maintained the Presenter as a mediating component within the triad. So then, while the Dolphin Smalltalk MVP and the Smalltalk-80 MVC patterns may appear similar on the surface, Presenters and Controllers differ in the purposes they were conceived to address.

The Fowler Patterns

During his research and preparation of material on presentation layer patterns in 2006 for an upcoming book, Martin Fowler decided that the treatment given to the design intensions behind today’s use of the Model-View-Presenter pattern be divided under the names Supervising Controller and Passive View. This distinction was made around the level of responsibility the Presenter/Controller component of the pattern takes on for presentation layer logic. The Supervising Controller and Passive View patterns are well distilled constructs which deal with the concerns of presentation logic apart from any specific domain logic strategy. This distilment renders patterns which describe solutions not specific to the Model-View-Presenter pattern, and are an excellent example of how patterns come about. While discussed here within the context of the Model-View-Presenter pattern, these patterns are best understood as facilitating patterns (as with the Observer Pattern) rather than variations of the Model-View-Presenter pattern.

The Supervising Controller Pattern

Overview

The Supervising Controller pattern separates an application’s concerns of presentation and presentation logic into the specialized components of View and Controller, with the View assigned the responsibility of simple presentation logic and the Controller assigned the responsibilities of responding to user input and handling complex presentation logic.

Structure

The following diagram depicts the structure of the Supervising Controller pattern:

6

Note: The model is shown with reduced emphasis to denote its peripheral role to the pattern description.

Components

The View is the visual components used within an application such as screens and widgets. The Controller is a component which processes user events and the complex presentation logic within an application.

Collaborations

Within the Supervising Controller pattern, Views delegate user events to the Controller which in turn interacts with the business domain of the application. For simple presentation logic, the View uses data binding techniques and the Observer Pattern to update itself when changes occur within the application. Complex presentation logic, particularly any logic one desires to unit test, is delegated to the Presenter.

The Passive View Pattern

Overview

The Passive View pattern separates an application’s concerns of presentation and presentation logic into the specialized components of View and Controller, with the Controller taking on the responsibility for responding to user events and presentation logic.

Structure

The following diagram depicts the structure of the Passive View pattern:

7

Note: The model is shown with reduced emphasis to denote its peripheral role to the pattern description.

Components

The View is the visual components used within an application such screens and widgets. The Controller is a component which processes user events and the presentation logic within an application.

Collaborations

Within the Passive View pattern, Views delegate user events to the Controller which in turn interacts with the business domain of the application and/or updates the View. The View maintains no link to the domain layer and relies solely on the Controller for all presentation related logic. Controllers within this pattern take on a mediating role between the Views and domain logic strategy used. This formalizes a role often erroneously ascribed to Controllers within the Model-View-Controller pattern.

The Presentation-Abstraction-Control Pattern

Overview

The Presentation-Abstraction-Control pattern is an architecture which separates the concerns of an application into a hierarchy of cooperating components, each of which are comprised of a Presentation, Abstraction, and Control. The PAC pattern seeks to decompose an application into a hierarchy of abstractions, and to achieve a consistent framework for constructing user interfaces at any level of abstraction within the application.

Origins and Motivation

The PAC pattern was conceived by Joëlle Coutaz in 1987. The goal of the pattern was to provide a model for developing interactive applications which bridges the gap between theoretical models for human/computer interaction and the practical concerns of building user interfaces. The original pattern description can be found in the publication: “PAC, and Object Oriented Model for Dialog Design”. In her article, Coutaz sets forth that the PAC model more closely follows the cognitive organization of human knowledge. That is to say, the human mind doesn’t perceive the world in layers, but rather in an interconnected web of abstract ideas.

Structure

The following diagram depicts the structure of the Presentation-Abstraction-Control pattern:

8

Components

The Presentation is the visual representation of a particular abstraction within the application. It is responsible for defining how the user interacts with the system. The Abstraction is the business domain functionality within the application. The Control is a component which maintains consistency between the abstractions within the system and their presentation to the user in addition to communicating with other Controls within the system. Note: Later descriptions generally use the term “agent” to describe each Presentation-Abstraction-Control triad.

Collaborations

Conceptually, the Presentation-Abstraction-Control pattern approaches the organization of an application as a hierarchy of subsystems rather than layers of responsibility (e.g. Presentation Layer, Domain Layer, Resource Access Layer, etc.). Each system within the application may depend on zero or more subsystems to accomplish its function. Each subsystem presents a finer grained view of an aspect of the overall system. By organizing systems into a hierarchy of subsystems, each of which are composed of the same PAC components, any level of granularity of the system can be inspected while maintaining the same architectural model. While interaction between the user and the application occurs through the Presentation components, interaction within the Presentation-Abstraction-Control pattern is accomplished exclusively through the Control element of each triad. The Control exists to bridge the gap between the presentation and the abstraction and maintains extensive knowledge about both components (6). Its responsibilities include updating the view, accessing the abstraction, maintaining state, thread management, flow control, and interaction with parent and child Controls. There exists no direct link between the Presentation and Abstraction within a PAC object (7).

Pattern Variations and Derivatives

From 1989 through 1995, the Commission of the European Communities funded two Human Computer Interface research projects under the names Amodeus and Amodeus-2 (8). Amodeus was an acronym for “Assimilating Models of Designers, Users and Systems”. During Amodeus-2, a researcher named Laurence Nigay, working under the supervision of Joëlle Coutaz, created the PAC-Amodeus Model. PAC-Amodeus is a model which blends the software components advocated by the Arch Model and the multi-agent model prescribed by the Presentation-Abstraction-Control pattern (9). The Arch Model was proposed by Len Bass at a UIMS Tool Developers’ Workshop in 1991 as a way to accommodate rapidly changing UI requirements (10) and itself was a derivative of the Seeheim Model developed in 1985. In many ways the Arch Model was similar to the Taligent Model which was to follow only a few years later. It prescribed a central Dialog Controller which mediated the interaction between the presentation and domain layer components, and used explicit components to define the interaction between the controller, presentation, and domain components. While the Arch Model prescribed specific components to accomplish its goal of flexibility and reuse, the underlying principle at work was its adherence to a layered organization of the application. While PAC provided a highly organized and uniform pattern for decomposing the tasks performed by an application, its insistence on a homogeneous design led to tightly coupled components which were difficult to maintain and reuse. The benefits of the layered approach were appreciated in the Arch Model, but the prescribed Dialog Controller was seen as too vague and all encompassing. It was therefore decided to use the Arch Model as the foundational model, but organize the tasks accomplished by the Dialog Controller into a series of PAC agents whose Presentation and Abstraction components mapped into other layered components within the Arch Model. Another derivative of PAC, by way of PAC-Amodeus, is PAC*. PAC* was developed by Gaelle Calvary, Laurence Nigay, and Joëlle Coutaz around 1997 (11). PAC* follows the PAC-Amodeus style of using the Arch Model as the base architecture with a dialog controller organized as PAC agents, but also incorporates concepts found within a model named Dewan’s Generic Architecture for addressing layer replication within multi-user applications. Full discussions of the PAC-Amodeus and PAC* are beyond the scope of this article, but a good summary of the Seeheim, Arch, PAC, PAC-Amodeus, and PAC* models among others can be found in a technical report by W. Greg Phillips entitled: “Architectures for Synchronous Groupware”. Another pattern worthy of note is the Hierarchical-Model-View-Controller pattern. While not a direct derivative of the PAC family of patterns, the HMVC pattern is often associated with PAC due to its similarities. The HMVC pattern was first described in an article which appeared in JavaWorld Magazine in July of 2000. Developed by Jason Cai, Ranjit Kapila and Gaurav Pal, the HMVC pattern is a prescription for organizing Model-View-Controller triads into a hierarchy for organizing the presentation layer of a rich client application such as Java Swing applications. While its organization of MVC triads into a hierarchy is similar to PAC, it differs in that Model and View components maintain the same observer relationship as within MVC, and more notably that it seeks only to address the presentation layer of an application rather than addressing the entire application architecture. While derived from the Model-View-Controller pattern, Controllers within the HMVC pattern are described as fulfilling a mediating role within the triad similar to the Supervising Controller pattern. Views receive the initial events generated by the user and decide which actions to delegate to the Controller. For this reason, the HMVC pattern is more similar to the Dolphin MVP pattern than with either the original Model-View-Controller or Presentation-Abstraction-Control patterns.

Pattern Comparisons

The following chart presents a quick comparison of the components represented in the various patterns presented in this article with a brief description of its role within the architecture.

Pattern Domain Presentation Control
Smalltalk-80 Model-View-Controller Model – domain objects within an application View- Visual presentation to the user Controller – human to Model connector; Intercepts user input
Taligent Model-View-Presenter Same as above Same as above Presenter – subsystem component connector; manages application subsystems
Dolphin Model-View-Presenter Same as above Same as above Presenter – presentation to domain connector; manages access to Model updates
Passive View N/A Same as above Controller – manages presentation logic
Supervising Controller N/A Same as above Controller – assists with presentation logic
Presentation-Abstraction-Control Abstraction – domain objects within an application Presentation – interactive component within the application Control – Presentation to Abstraction connector

Conclusion

The Model-View-Controller, Model-View-Presenter, and Presentation-Abstraction-Control patterns are similar in many ways, but have each evolved to address slightly different concerns. By becoming familiar with these patterns and other related architecture models, developers and architects will be better equipped in choosing an appropriate solution in their next design endeavor, or possibly in the creation of future architecture design patterns.

References

1. Reenskaug, Trygve. The original MVC reports. Trygve Reenskaug Home Page. [Online] May 12, 1979. [Cited: July 07, 2007.] http://heim.ifi.uio.no/~trygver/2007/MVC_Originals.pdf.

2. Steve Burbeck, Ph. D. Applications Programming in Smalltalk-80(TM): How to use Model-View-Controller (MVC). The UIUC Smalltalk Archive. [Online] March 4, 1997. [Cited: July 7, 2007.] http://st-www.cs.uiuc.edu/users/smarch/st-docs/mvc.html.

3. Potel, Mike. [interv.] Derek Greer. July 18, 2007.

4. Reenskaug, Trygve. The Model-View-Controller (MVC) Its Past and Present. Trygve Reenskaug Home Page. [Online] August 20, 2003. [Cited: July 7, 2007.] http://heim.ifi.uio.no/~trygver/2003/javazone-jaoo/MVC_pattern.pdf.

5. Fowler, Martin. Patterns of Enterprise Application Architecture . s.l. : Addison-Wesley Professional, 2002. 978-0321127426.

6. PAC, an Object Oriented Model for Dialog Design. Coutaz, Joëlle. [ed.] H-J. Bullinger and B. Shackel. North-Holland : Elsevier Science Publishers, 1987. Interact’87.

7. Calvary, Gaëlle, Coutaz, Joëlle and Nigay, Laurence. From Single-User Architectural Design to PAC*: a Generic Software Architecture Model for CSCW. [http://www1.acm.org/sigs/sigchi/chi97/proceedings/paper/jcc.htm] Grenoble, France : s.n., 1997.

8. AMODEUS-2 – Multidisciplinary HCI Modelling. http://kmi.open.ac.uk. [Online] 1997. [Cited: August 20, 2007.] http://kmi.open.ac.uk/people/sbs/amodeus.html.

9. Nigay, L. and Coutaz, J. Software Architecture Modelling: Bridging Two Worlds Using Ergonomics and Software Properties. http://iihm.imag.fr/. [Online] [Cited: August 20, 2007.] Software Architecture Modelling: Bridging Two Worlds Using Ergonomics and Software Properties.

10. Sheppard, Sylvia. REPORT ON THE CHI ’91 UIMS TOOL DEVELOPERS’ WORKSHO P. SIGCHI Bulletin. January 1992, Vol. 24, 1.

11. Coutaz, Joëlle. Correspondance with Joëlle Coutaz. [Email]. August 20, 2007.

12. Fowler, Martin. GUI Architectures. http://www.martinfowler.com. [Online] July 18, 2006. [Cited: July 03, 2007.] http://www.martinfowler.com/eaaDev/uiArchs.html.

13. —. Supervising Controller. http://www.martinfowler.com. [Online] June 19, 2006. [Cited: July 03, 2007.] http://www.martinfowler.com/eaaDev/SupervisingPresenter.html.

14. —. Passive View. http://www.martinfowler.com. [Online] July 18, 2006. [Cited: July 3, 2007.] http://www.ibm.com/developerworks/java/library/j-mvp.html.

15. Potel, Mike. MVP: Model-View-Presenter – The Taligent Programming Model for C++ and Java. http://www.wildcrest.com. [Online] 1996. [Cited: July 15, 2007.] http://www.wildcrest.com/Potel/Portfolio/mvp.pdf/.

16. Phillips, W. Greg. Architectures for Synchronous Groupware. Kingston, Ontario, Canada : s.n., May 6, 1999. ISSN 0836-0227-1999-425.

17. A metamodel for the runtime architecture of an interactive system: the UIMS tool developers workshop. 1, New York, NY : ACM Press, January 1992, ACM SIGCHI Bulletin, Vol. 24, pp. 32-37. ISSN 0736-6906.

18. Understanding JavaServer Pages Model 2 architecture. http://www.javaworld.com. [Online] December 29, 1999. [Cited: February 8, 2010.] http://www.javaworld.com/javaworld/jw-12-1999/jw-12-ssj-jspmvc.html.

MVC模式理解——当年给我一个browser多好

 

————————————————————————————————————

来源:http://www.cppblog.com/darkdestiny/archive/2009/01/13/71944.aspx

————————————————————————————————————

以前一直无法舒坦的理解,MVC模式是怎样实际应用到一个程序上的。

这两天因为工作google出一幅图,然后恍然大悟。

图1.

mvc-rails

问题就出在以前所看过的文章上根本没有提过browser这层。导致我无法正确理解view的责任、controller的责任,以及两者明明是分层的,为什么却是循环依赖。

我将browser介入其中,重新思考MVC模式究竟如何部署到程序结构上。

图2.

mvc

计算机前的用户,只会和browser打交道,也就是整个应用程序的界面部署,各种窗口,包括菜单、按钮、子对话框等等。

我把整个界面部署的代码,全部放置到browser模块下。此时无需model、view、controller,仅有browser的代码,我们就可以给用户显示这个界面。

接下来我引入model模块,这个模块的代码和窗口无关、和控件无关、和HWND无关。就是一个后台运行的东西,不需要面向任何用户。

model包含了业务的本质数据结构和逻辑流程。

然后我引入view模块,view模块代码的责任就是,如何利用browser显示model的内容。

这个责任有两个潜在意义:

1. browser模块的代码不会去访问model模块的内容,并显示在browser相应的窗口上。

2. 在没有controller的情况下——用户不能操作程序界面上的任何菜单、按钮,只能看不能摸,view模块能够在browser上给用户显示model的内容。

因此,view模块在MVC模式中所能做的就是:

1. 访问model模块,获取内容。

2. 访问browser模块,修改窗口。

最后引入controller模块。

用户在计算机前看着browser,浏览业务数据,他肯定会做一些操作,比如按下按钮,选个菜单或者其他什么的。

用户修改model模块的每一个决定性操作,就映射在controller模块的一个接口上。controller模块的责任是,代表用户的每一个动作,并分解为多个view做什么,model做什么的调用。这个动作必须有操作model或者view的代码,不然这个动作放在browser模块下就可以了。

现在合起来分析个例子,用户通过browser向model添加一个任务。

按下确定按钮后,browser读取其他子窗口的输入数据,当做参数传递给controller模块对应的调用。

l controller模块不会主动的从browser中的控件中读取数据。如果用户的动作足够简单,controller有可能就仅仅作为一个中间层调用model模块。

controller模块将用户的动作分解为一些更细致的调用:

1. 让model添加新任务。(不关心model怎么做)

2. 从model中获取新任务的信息。

3. 将新任务的信息传递给view,让他在browser显示出来。(不关心view怎么做)

从controller的动作分解中可以看出:

l 和之前view直接访问model获取数据不一样,这里controller从model获取数据,并交给view。仅由controller访问model是有好处的,使得view和model没有了耦合。

l 这里有一个微妙的循环依赖关系,browser依赖于controller,controller依赖于view,view又依赖于browser。

l 解开这一依赖的方法1,提取一个view interface,让controller依赖于他,而不是依赖于view。提取controller interface也是同理。

l 方法2,controller不依赖于view,让view自己负责根据model的状态改变显示,即controller负责修改model,view负责读取model。

l 不过,view和model之间通过controller传递数据是有好处的,除了耦合之外,另一个关键的地方是,可以在controller中过滤数据,而不用修改model。

l 这两个方法没有最好,只有根据具体的情况选择最合适的做法。在程序足够小的情况下,其实是不需要把模块划分得那么清楚的。

杀出重围3:人类革命 Augmentation

by Aivboh

1. Arm Augmentations

1.1 Cybernetic Arm Prosthesis

Deus Ex Human Revolution Augmentation (13)

Instant Take-Down (Default)

Cost: 2 points, 1 cell

默认升级。

Punch Through Wall

Cost: 1 point, 1 cell

不需要加。

这个技能很早就可以用到(在Detroit关闭信号塔),但实际上我很少用到此技能。因为砸墙会搞出很大的动静,一个不小心,Ghost经验奖励就没了。

Recoil Compensation 1

Cost: 1 point, none

Recoil Compensation 2

Cost: 1 point, none

不需要加。

这两个强化可以让你使用重型武器更加得心应手,但实际上用的最多的还是10mm pistol(除了最后一关打僵尸,幸亏当时带了一把左轮啊。),火箭筒、重机枪什么的包包实在是没有地方装。而且还有那天杀Typhon系统,要重武器做什么呢。

Move/Throw Heavy Objects

Cost: 1 point, none

必加。Detroit 1可用。

此强化随时都会用到,至少我目前为止,不知道没有这个技能如何做Detroit的第一个支线任务(虽然可以从警察局绕进去,但是还是出不来啊)。

Carrying Capacity 1

Cost: 1 point, none

Carrying Capacity 2

Cost: 1 point, none

Carrying Capacity 3

Cost: 1 point, none

这三个强化早晚都会加满的。我在离开Detroit 1的时候就已经升满了。

1.2 Aim Stabilizer

Deus Ex Human Revolution Augmentation (14)

Aiming Motion Control 1

Cost: 1 point, none

Aiming Motion Control 2

Cost: 1 point, none

可选。

顾名思意,开镜的时候准星不太晃了。不过,可以开镜的时候通常是比较悠闲的时候,瞄准快点慢点影响不大。

2 Back Augmentations

2.1 Reflex Booster

Deus Ex Human Revolution Augmentation (17)

Multiple Take-Down Upgrade

Cost: 2 points, none

推荐。Hengsha 1 可用。

如果是潜入流,化身Snake的话,这个技能基本是必加的。从去Hengsha开始,就会出现很多两个一组的敌人,如果没有这个强化的配合,想多拿经验(比如Ghost奖励)是不可能的。

2.2 Icarus Landing System

Deus Ex Human Revolution Augmentation (18)

Descent Velocity Modulator

Cost: 2 points, none

推荐。Hengsha 1 可用。

在潜入永泰制药的时候,如果有降落系统加持,可以轻松取得高级通行证,大摇大摆的走进去。既使不考虑任务需要,它也可以帮你节省大量跑路时间,直接跳楼(井)无视梯子吧。

3 Cranium Augmentations

3.1 Social Enhancer

Deus Ex Human Revolution Augmentation (1)

Cost: 2 points, none.

可选。Detroit 1 可用。

这个技能用来降低游戏的对话部分的难度,它直接告诉你被说服对象的弱点,避免你漫无目的的猜测选择。当然,如果你有攻略的话,有它没它完全无所谓。因为,既使没有这套分析系统,NPC也是可以被说服的。没有攻略的话,SL大法吧。

该技能的其它用处就是帮你省一点小钱。只有一个支线任务(Ladies Man)强制需要该技能才能完成一个特定成就。成就什么的,拿完读档吧。

3.2 Wayfinder Radar System

Deus Ex Human Revolution Augmentation (2)

Radar 1 (Default)

Cost: 1 point, none

默认升级

Radar 2

Cost: 1 point, none

可选。

扩展雷达范围,让潜入变得更简单一点。对作战能力没啥帮助。

3.3 Infolink

Deus Ex Human Revolution Augmentation (3)

Cochlear Implant (Default)

Cost: none, none

Subvocal Communication Implant (Default)

Cost: none, none

默认升级。

远程心灵感应系统。

3.4 Stealth Enhancer

Deus Ex Human Revolution Augmentation (4)

Noise Feedback

Cost: 2 point, none

不需要。

让你的声音脚步声不容易被听到(i.e. 扩大侦听免疫范围)。大多数时候,你都在蹲着。而且,如果扩大雷大范围的话,这个技能变得完全没有意义。

Cones of Vision

Cost: 1 point, none

不需要。

显示NPC视野范围。其实算是比较有效降低潜入难度的技能,不过你可以用SL大法熟悉一下NPC视野就行了。你会了解到,其实径直走向两个对眼的敌人,他们是看不见你的。Take down.

Last Known Location Marker

Cost: 1 point, none

不需要。

不解释。

Mark and Track 1.0, 2.0, 3.0

Cost: 1 point per augmentation, none

不需要。

细胞分裂里有类似的技能,不过那个至少可以用来发动杀阵。这个什么用都没有。

3.5 Hacking Capture

Deus Ex Human Revolution Augmentation (5)

Capture 1, 2, 3, 4, 5

Cost:1 point per augmentation, none

1-3必加,4推荐,5可选。

前3级基本是伴随整个游戏过程的,在Detroit 1你可能会很早加到3级破解。4级在Hengsha 1的Hive酒吧会出现,在Hengsha 2会变得很常见。5级是有用的,在Hengsha 1的Hive酒吧,甚至Detroit 1的武器仓库你就会遇到。但是5级Hacking的问题是,考虑一个Parixs点值5000经验,我怀疑全游戏的5级device加起来都无法弥补这个损失,完全亏损啊。

Camera Domination (Default)

Cost: 1 point, none

默认升级

Turret Domination

Cost: 1 point, none

Robot Domination

Cost: 1 point, none

可选。

虽说这两个技能都不错,但是很可能要后期你才会点。

3.6 Hacking Analyze

Deus Ex Human Revolution Augmentation (6)

Detection Feedback

Cost: none, none

Analyze All Datasotres

Cost: 1 point, none

其实用不到,不需要的说。

3.7 Hacking Fortify

Deus Ex Human Revolution Augmentation (7)

Fortify 1, 2, 3

Cost: 2 points in total, none

尽量吧。

在加满该系之前,确保Hacking Stealth已经加满。

3.8 Hacking Stealth

Deus Ex Human Revolution Augmentation (8)

Stealth 1, 2, 3

Cost: 3 points in total, none

必加。

想要Hack,你会很快发现这才是必备技术。不过发现机率是有下限的(15%)。

4 Eye Augmentations

4.1 Smart Vision

Deus Ex Human Revolution Augmentation (15)

Wall-Penetrating Imager

Cost: 2 points, low

可选。

透视术。这一类消耗电池技能的主要问题是和Takedown冲突,由于充电系统只充一格电,如果你透视、隐身、消音的话,Takedown就没法用了。所以想要连招的话,身上要备好能量食品,最大敌人就是物品栏格数。而且你还需要升级电池格数到至少3格,才不会浪费能量食品的作用。

4.2 Retinal Prosthesis

Deus Ex Human Revolution Augmentation (16)

Retinal HUD (Default)

Cost: none, none

默认升级

Flash Suppressant

Cost: 1 point, none

可选。

如果是英雄萨姆,还是比较有用的。

Cooldown Timer

Cost: 1 point, none

不需要。

HUD显示强化。

5 Leg Augmentations

5.1 Cybernetic Leg Prosthesis

Deus Ex Human Revolution Augmentation (21)

Jump Enhancement

Cost: 2 points, none

Sprint Enhancement

Cost: 1 point, none

Run Silently

Cost: 1 point, low

Sprint Silently

Cost: 1 point, low

Jump/Land Silently

Cost: 1 point, low

不需要

全是跑路技能。消音技术的问题同上,消耗电池格数,但是充电系统只充一格电。

6 Skin Augmentations

6.1 Dermal Armor

Deus Ex Human Revolution Augmentation (19)

Damage Reduction 1

Cost: 2 point, none

Damage Reduction 2

Cost: 1 point, none

Damage Reduction 3

Cost: 1 point, none

不需要。

看起来很美好,但是Shotgun还是能一枪秒了你。

EMP Shielding

Cost: 2 points, none

加不了。

不错的技能,问题是学完需要5点,而前置技能纯粹是鸡肋。

6.2 Cloaking System

Deus Ex Human Revolution Augmentation (20)

Base Longevity

Cost: 2 point, 1 cell for 3 second

Longevity Upgrade 1

Cost: 1 point, 1 cell for 5 second

Longevity Upgrade 2

Cost: 1 point, 1 cell for 7 second

可选。

很实用,但同时能量消耗很大的技能,可以无视激光。一旦选择是需要加满的,而且你还需要强化电池系统,同时备好能量食品,总之成本很高……但是大多数情况用不到,我能想到就是冲进人堆里放台风。飞行员我就是这么救的,但是5格电池也只够我用一次台风……其实一颗毒气弹/手雷、一颗EMP就能解决的问题……

7 Torso Augmentations

7.1 Sentinel RX Health System

Deus Ex Human Revolution Augmentation (9)

Cardiovetor Defibrillator (Default)

Angiogenesis Protein Therapy (Default)

默认升级。

7.2 Sarif Series 8 Energy Converter

Deus Ex Human Revolution Augmentation (10)

Base Energy Level (Default)

Cost: none, none

默认升级

Energy Level Upgrade 1

Energy Level Upgrade 2

Energy Level Upgrade 3

Cost: 1 point per augmentation, none

可选。

如果升级了隐身等其它消耗能量的技能,可能需要3级5格电才能充分利用。如果要不浪费能量食品的效果(充至3格),应该至少升1级。

Base Recharge Rate (Default)

Cost: none, none

默认升级

Recharge Rate Upgrade 1

Cost: 1 point, none

Recharge Rate Upgrade 2

Cost: 1 point, none

推荐。

不错的技能,节省等待时间,可惜的是还是只充一格电啊。在加该技能之前,优先Multiple Take-Down Upgrade.

7.3 Implanted Rebreather

Deus Ex Human Revolution Augmentation (11)

Chemical Resistance

Cost: 2 points, none

可选。

还不错,无视毒气。在永泰制药你会遇见扔毒气弹的敌人,淡定的蹲着就可以了。有些区域布满毒气,直接走过去。

Hyper-Oxygenation 1

Cost: 1 point, none

Hyper-Oxygenation 2

Cost: 1 point, none

不需要。

跑路技能。

7.4 Typhoon Explosive System

Light Damage Variant

Cost: 1 point, none

Heavy Damage Variant

Cost: 1 point, none

必加。

值得加满的技能。建议在打第二个BOSS(Hengsha 1结尾)之前加至少一级。有了Typhoon,和那占包包的重型武器说再见吧。

参考资料:

http://www.ign.com/wikis/deus-ex-human-revolution/Augmentations

关键字:

杀出重围,人类革命,技能,加点

复杂理论收集

Clipped on 12-April-2011, 1:21 AM from 复杂理论收集

2011-03-24 20:53:36 来自: Jack

隐藏的逻辑 http://www.douban.com/subject/3766438/

1. 复杂的两个核心问题: 系统对于初始条件的敏感和反馈。

缔结默契:社会昆虫之间的协作方式,个体之间并不直接交互,而是通过改变环境间接达到交互。

知识的演化和变化,人群交互加速了显性知识和隐性知识之间的转移和传递,同时将隐性知识不断的显性化,促使不断加速互联网应用的社会化进程。

社会性软件,系统的社会化,把自下而上的社会建构原则纳入系统设计。通过用户的引入到互联网,使互联网的应用随着群体的观点和行为的变化实现适应性的改变,从而推动互联网应用的自行演化。这种自行演化,产生了大量多重非线性机制,促使涌现的产生

系统的适应性设计,让一些简单的交互规则,反馈机制的设计,可以形成很复杂的多重反馈结构

2. 社会原子,人的心理和群体行为是两回事,分析群体行为更应该把人作为分子或者原子。

互动模式,人类并没有传统社会学认为的那样“特殊”,人不过是自然界的一部分,是人类社会的“社会原子”;而人类社会之所以纷繁复杂并不是因为 “人”本身复杂,而是因为人们的“互动模式”的千变万化。“互动模式”,大概就是包括布坎南先生在内的很多社会物理学研究者眼里的人类社会之物理学法则。

自组织,市场具有自我组织的魔力,自组织的本质是一种自我生成的模式,比如亚当斯密看不见的手和哈耶克的自发性秩序。

同一性,当人们自由自在的时候,他们会相互模仿… 一个赋予个体无限自由的社会,往往会达到令人惶恐的同一性。

互惠性,人类互惠性的目标是为了建立声誉、积累好处。人类历史就是一场在合作能力或强或弱的群体之间的斗争,合作能力强的胜出。

3. 模式分析。

3.1 要思考的是模式,不是人,大规模的模式形成和个体的特征无多大关系。

3.2 我们对于辨别模式,适应不断变化的世界,具有超级好的能力。

3.3 要关注重要的细节,忽略不重要的细节,市场往往在可预测性和不可预测性边缘徘徊。

http://www.douban.com/review/2214936/

http://www.douban.com/review/2341955/

从牛顿达尔文到巴菲特投资的格栅理论 http://www.douban.com/subject/1022739/

5. 复杂适应系统,每一个复杂系统其实都是由许多平行作用且相互影响的独立个体组成的网络。一个系统成为复杂系统的关键因素,是系统中的个体能够在于其他个体的相互作用中积累经验,在适应的环境中变化自己。

7. 经济特性,圣塔菲认为经济的四大特点是:松散的相互作用,不存在称霸世界之王,不断的适应过程和动态不平衡。

8. 反馈,复杂适应系统的基本元素是反馈,系统中的个体首先形成自己的期望或者模型,根据这些模型计算出的预测来行动。

10. 自组织,自组织系统有三大明显特征。(1)复杂的全球性行为是由简单的当地处理者组成的。(2)各种个人意见的贡献构成了解决方法。(3)系统强大的功能远比任何一个独立处理者要大得多。

12. 集体决定,只有系统中的个体都往单一集体选择方向积累信息时才可能产生集体决定。为了达到这个共同决定,所有的个体并不必拥有相同的信息,但他们必须对不 同机会的理解相同。这个共同理解在所有复杂系统的稳定性中起着关键的作用。系统的共识程度越低,其不稳定性越大。

http://www.douban.com/review/2973723/

http://www.douban.com/review/2970660/

成败就在刹那间 http://www.douban.com/subject/3346153/

1. 认知的进化,认知的进化是建立在装满了“本能”的适应性工具箱的基础之上的。适应性工具箱包括三层:进化能力,利用进化能力构建的积木块,由积木块构成的经验法则。

2. 推测,无论是感知,信念还是欺骗,我们大部分的直觉行为都可以被某种已经适应于我们周围世界的简单机制所描述和形容,也就是推测。我们大脑正是通过对世界的推测来帮助我们,如果没有推测,我们虽然能够看到细节,却毫无结构。

3. 感知系统,一个良好的感觉系统必须深入到所给予的信息表层的背后,它必须“创造”一些东西。你的大脑看到的东西,远比你的眼睛看到的多。

4. 自由选择的两难困境,拥有的选择机会越多,其内心冲突的可能性就越大,对照比较的困难程度也越高。过多的选择/产品和意见,反而会损害商家和顾客双方。

5. 简单,在一个不确定的世界中,简单法则对于复杂现象的预测效果高于复杂法则能达到的程度。

7. 模仿,经验法则让我们可以以一种对环境敏感的方式进行模仿。如果你的周围世界变化很慢,那么就进行模仿,否则就根据自身的经验进行学习。(或者模仿那些比你更聪明,对新环境更适应更快更迅速的人)

8. 简单,简单是对不确定性的适应。在一个不确定的环境当中,良好的直觉必须忽略掉一些信息。

9. 人类理性行为的剪刀,构成两侧刀片的,是任务所在的环境结构和行动者的计算能力(Herbert Simon)

10. 逻辑与直觉的冲突,逻辑准则对我们的文化视而不见,忽略了我们进化的能力和周遭的环境结构,那些从纯逻辑角度通常被看作是推理错误的感知,事后被证明反而是在现实中更高智慧的社会判断。

http://www.douban.com/review/2955884/

链接网络新科学 http://www.douban.com/subject/2149971/

1. 引爆点,来自连接者,连接者(带有极大量链接的节点)是引爆流行的真正原因。

2. 中心节点,在大部分复杂网络中,都存在中心节点,他们的广泛存在,成为这个广泛联系的世界的基本特性。中心节点是网络中的基本组成部分,它们起的作用非常重要,保证了网络的高可靠性,也使网络呈现小世界的特点。

3. 钟形分布与幕率分布,感觉这个和黑天鹅那本书很类似,钟形就是平均斯坦,幕率分布就是极端斯坦。

4. 符合钟形分布的是随机网络,比如公路图,符合幕率分布的是无尺度网络,比如飞机航线图。

5. 钟形分布同时意味着无序状态,幕率分布同时意味着有序状态。

幂律分布的最突出特点,不仅是其中有许多小事件,而且是许多小事件,而且是许多小事件伴随着少数极大的事件。这种超乎寻常的大事件是不可能存在于 钟形曲线内的。注意,在这分布图的末端,幂律分布和钟形分布也存在重要的性质差异,钟形曲线末端呈指数递减,递减速度比幂律曲线大。出现这种呈指数级递减 的末端,原因在于钟形曲线上缺乏中心节点。相比之下,幂律曲线递减速度较慢,允许罕见事件如中心节点的存在。

中心结点、80/20、幂率分布,说的都是同一件事情,然而长尾的流行和Niche Market的日益重要告诉我们:要重视中心结点,但不要忽视普通节点

6. 相变,相变意味着从无序到有序。从无序过渡到有序的关键:节点由无规则分布到社会化分布

缓慢降低的幂律分布很自然地能和高度链接的异常节点结合起来,它预言每个无尺度网络都会有几个大的中心节点确定网络的拓扑结构。该拓扑结构决定了真实网络的结构稳定性、动态行为、稳健性(robustness)、容错性以及承受攻击的能力。

1965年,leo kadanoff突然意识到:在临界点附近,我们就不能再把原子当成独立的粒子看待,而应该把它们看作是属于一个个社区,共同行动的群体。可以把原子看做是装在一个个盒子里,每个盒子里的原子都有同样的行为方式。

kenneth wilson的重正化理论证明了每当无序变成有序的临界点,即由混沌到有序的临界点的时候都会发现幂律的存在,他给相变理论的金字塔添上了顶端的最后一块 石头,并于1982年获得诺贝尔物理学奖。一旦系统被迫发生相变,一切随之改变,继而出现幂律。相变理论表明了从混沌到有序的过程受到自组织的影响,这是 幂律造成的。幂律的存在,将复杂网络从er模型的随机性的丛林里拯救出来,将其放在色彩斑斓的,充满了丰富理论营养的自组织的舞台的中心。

7. 无尺度网络的两个特征:增长、优先情结。造就了富者愈富;而合理利用适应性,是后来者打破这一法则的关键

8. 适应性概念:后发先至,在呈现适者致富的网络中,竞争会导致无尺度拓扑结构的产生。

http://www.douban.com/review/1682201/

http://www.douban.com/review/2950184/

http://www.douban.com/review/1947430/

非理性市场与蜥蜴式大脑思维 http://www.douban.com/subject/3099576/

模式,从随机走势中寻求模式和规律。蜥蜴式大脑善于在不合逻辑的行为中寻求合乎逻辑的模式。

情绪,. 一项有趣的测试,第一, 所有的商人—即使是经验最丰富的人—对市场信息都反应出明显的情绪波动。 第二, 经验丰富者的情绪化反应比经验不足的人要弱一些。

“研究还发现另一个有趣的现象,多利用认知能力的人的挫折感就越弱。准确地说,前额叶越活跃,对痛苦和挫折的敏感性就越低。成功需要利用认知能力去控制蜥蜴式大脑思维,这是本书的一个重要主题。”

http://www.douban.com/review/2893259/

两种学习方式,习惯化和敏感化,通过习惯化,动物因某个刺激的微弱而学会忽略它,通过敏感化,动物因为刺激的重要性而重视它。(习惯化帮助提高效率,敏感化帮助提升效果)

敏感化学习使神经元长出新的突触末端,习惯化使神经元的突触数目减少。

http://www.douban.com/subject/1944205/

协同学 http://www.douban.com/subject/1013152/

8. 在各种领域中结构的发展有着相同的规律:某种有序状态不断增长,直到最后它占据优势并支配一个系统的所有部分,迫使其他部分进入这种有序状态。常常是一种不可预见的涨落时两个等价的有序状态间作出了最终选择。

5. 外部条件的改变将会使系统的某种确定状态变得不稳定,并且能够为一种新的、有时甚至完全不同的状态所代替,系统的不同部分,将被迫进入新的状态,他们将受到序参数的支配。

6. 条件的微小变动也可能导致完全不同的状态。

7. 流行的舆论起着序参数的作用,它支配着个人的意见,形成一种大体上是一致的舆论,借以维持其自身的存在。

http://www.douban.com/review/1605825/

沙地上的图案——计算机、复杂性和生命 http://www.douban.com/subject/1838594/

模块结构是处理复杂性的重要工具,模块是数据及数据读取和控制指令的集合,通过封装数据及用有限的方法进行读取,软件开发的复杂任务可以分解为可处理的较小模块进行。

科学的两条规律 一、试图解释一切的理论(万能理论)往往什么都解释不了。二、观察事物的新方法、特别是这些方法能够将表面看起来不同的事物联系起来时,通常会导致对自然界更深刻的见解。

9. 线性系统倾向于消除微小变化,而非线性系统倾向于放大该变化…变化的加强是因为简单个体间存在的无数的相互作用而形成的。

14. 生物系统是高度适应性的,但他们也具有可观的冗余度…..如果我们没有完全理解复杂系统的动力学,我们就无法把事情真正做好。

http://www.douban.com/review/1605760/

隐秩序:适应性造就复杂性 http://www.douban.com/subject/1071936/

一般的复杂系统具有什么样的共同特征呢?首先,所有这些系统都是由大量被称为主体的元素组成的系统,这些主体整体能够具备第一章提到的聚集、非线性、流、多样性这四个特性,每个主体都具备内部模型、标识、积木这三种机制。

复杂性、风险与金融市场 http://www.douban.com/subject/1192910/

证券市场需要不确定性才能得以存在和延续。不确定性是市场的稳定性和创新性的主要来源。它需要不确定性保持其竞争机制永久不衰,而竞争正是市场的生命之源

复杂系统具有局部杂乱无序和整体结构有序的特性。整体的结构维持整体的聚合力,局部的杂乱无序导致创新和活力。在自由市场经济中,竞争是局部杂乱 无序的源泉,而规则是维持整体结构有序的保证。因此,竞争需要高度的不确定性,这与我们在现实中的感受是一致的。企图减少不确定性的做法只能破坏自由市场 经济的特性。

奥地利经济学派认为当存在共同目标或相同知识的时候,个体就会产生自组织现象。事实上,由奥地利经济学派发展出来的许多概念与复杂性科学理论是相吻合的。只不过,复杂性科学理论把奥地利经济学派的观点数学化了。

这两大研究领域的结合就可以体现自由市场经济的精髓,特别是,我们将看到不确定性对自由市场的存在是多么必要。事实上,所有既需要变化又需要稳定 性的系统都需要不确定性。自由市场需要稳定,以便使人们对经济保持信心,与此同时,自由市场也需要一定的涨落。保持自由市场基本活力的机制是竞争,而竞争 需要不确定性

任何复杂系统都具有一定的功能或目的。这种功能是一种状态,而不是一个结果。整个生态系统通过稳定的能量转换来维持有机体的生存。自由市场经济通 过想赚钱的人们之间的商品和服务贸易来促进经济的发展。复杂系统追求的目标不是一种静态‘平衡’,相反,它追求的是一个不断变化,不断创新,同时还要保持 相对稳定的动态演化状态。至于它是怎样达到这种状态的,其详细过程并非一成不变。因为复杂系统到达某一稳定状态并不需要特定顺序的事件发生,所以,尽管环 境中存在着一些无法预料的变化,系统也总是能够加以克服,并能够创造性地调整自身以实现其目标。系统能够从不确定性中产生秩序,但这种秩序的‘独特’特征 是不可预知的。复杂系统在将不确定性转化为秩序的同时,也在产生着更多的不确定性

复杂系统是随着时间不断演化的,虽然它们也难以预测,但是他们需要依据过去来理解现在,未来的可能性取决于人们过去的选择,而适合我们的选择在很 大程度上依赖于我们过去所做出的决定。尽管复杂系统具有‘路径依赖’性,但它们并不具有‘前定’性。事实上,复杂系统的一个明显特征就是它能够通过多种手 段来实现同一目标,如果气候、土壤等条件具备,橡树种子总是能够长成橡树。

复杂系统的局部具有不确定性,但其整体却具有确定性。复杂系统不断地变化,并且能够带来一些意想不到的惊奇。它们将不确定性转化为秩序,又将秩序 转化为不确定性。复杂系统随时间不断地演化和变化着,其背后并不存在什么中心策划者。复杂系统随处可见,事实上,现实生活本身就是一个巨大的复杂系统

http://www.douban.com/review/2212094/

“类型I:简单线性——高的长期和短期可预测性。

“此类过程具备高度短期和长期可预测性,因为在一个因素和其对过程产生的影响之间存在直接的一对一的对应关系。……线性过程是最简单的过程。不幸的是,在现实生活中,几乎不存在真正被线性关系驱动的系统。线性系统不能抵抗外部冲击。

“类型II:非线性动力(混沌)——高的短期可预测性,低的长期可预测性。

“当考虑一个多因素的过程,例如气候系统,一个小的影响后来能引起一个大的反应。这类混沌过程在短期内通常能够进行预测,因为短期内的相互关系近 似是线性的。……所以,这是一种非线性的关系,在近处,几乎是线性的;可是,离开当前位置越远,非线性就越明显。因此,一个非线性的动力系统(通常被称为 混沌系统)在短期内是可以预测的。但在长期内不能加以预测。

“混沌系统具有短期的稳定性,但不知长期内是否稳定。外部的冲击将导致混沌系统进入完全不同的轨道。

类型III:非线性随机(概率混沌)——低的短期和长期可预测性。

“另一种典型的非线性相关称做非线性随机相关。假设大多数的‘无序’过程均服从正态分布(或钟形曲线),这是错误的。存在一些随机过程,不服从该 假设,它们的概率分布是完全不同的。尽管很难描述,一个非线性随机过程的概率分布变化是有规律的。但它们不会收敛到一些通常的分布族,例如正态分布。

“类型IV:复杂——高的长期可预测性,低的短期可预测性。

“复杂过程,我们已经谈到,其特征是整体的结构性和局部的随机性。这些特征能够转变成高的长期可预测性和低的短期可预测性。整体结构性允许我们预 测除了细部之外的典型的特征。……复杂性让我们能够预测长期的结果,但是近期的结果总是未知的和不可能知道的。如果复杂过程在近期内是可以预测的,那么它 将不再是复杂的过程。

“我们已经知道,复杂过程对外部冲击是具有弹性的。一个复杂过程能够从冲击中加以学习,然后依然能够通过采取替代的途径,达到其目标。复杂过程具备创新性、适应性和能够进行学习的特点,它也是自组织的过程。

http://www.douban.com/note/87408954/ 崩落的沙粒——思考自组织的临界性

圆桌会议与天才

卖萌

——————————————————————————————————————————

Clipped on 09-March-2011, 1:22 AM from Worlds » 圆桌会议与天才

mujun 拍脑袋 2011-02-01

下午花八毛九分钱在Amazon上买了一本Kindle版托克维尔的《论美国的民主》,放六寸屏幕上显示正正好。啊哈哈哈哈,其实庄重优雅的托克维尔也很适合用Kindle来看啊,那么轻,最好不过的bedtime reading了。

下午继续看哈贝马斯的《公共领域的结构转型》。第一次看其实只是知道了大概,想着他是要用历史上那个可能跟本就没有存在的所谓公共空间来批评晚期资本主义阶段市场和国家官僚机构力量对于生活世界无孔不入的渗透。这次着重看他怎样论述这个“转型”的过程。哈贝马斯评述了不同流派的学者怎样描述和解释公 共空间的内在矛盾。很可惜我只能大致看懂马克思和经典自由主义这两部分,而前面写黑格尔和康德的就绕不过来了。读到哪里是头。悲摧啊。

到四点左右饿得眼冒金星,出门买了一点french fries。吃完以后收邮件发现Waston晚上有一个关于中东局势的圆桌会议。有可能是因为吃得太撑,我一点想要回家柴米油盐的心思都没有了,干脆就跑去Waston关心家国天下。没想到关心家国天下的人还特多,主会场里挤满,只能去分会场里坐在地上看电视转播。大家都high到了,可真问起未来走向又是语焉不详,谁让社会学家总是那么擅长预测已经发生了的事情呢。为首的那个装得很萌地问大家,到底是极权还是民主更有利于一个地方的“稳定”,我只好继续淡定地吃我带去的薯条。

06年在中文大学游学的时候参加过一个专门开给本科低年级学生的社会学入门seminar,每周读点书,完了大家凑在一块儿讨论。因为参与的学生都不怎么读书而且大家英语也不灵光,负责的老师张德胜,那会儿已经快要退休了,见到大家不说话了就放电影。有一回聊爱情,他老人家给我们放了一个片儿,说他看了特别感动,就是讲贝多芬的Immortal Beloved。我倒没被那片里的爱情感动,可是我清楚地记得自己看到某一个地方的时候掉了眼泪,就是落魄的贝多芬被一帮小孩群殴。

我突然想到,看看我们这群平常的人对天才都做了点什么。我们平日里从围观他们中获得了多少乐趣,真碰到一个在身边,却免不了带给他们那么多痛苦。于是我暗下决心如果我的生活里也能碰上一个天才,即使他看上去再怎么神神叨叨,我也肯定想方设法待他好。要让社会里多点宽容,所以对于神经病亦应不失温情。

我有时候觉得这真是一个很平庸的时代。你看看时髦的教育理念都在说什么呢——要让小孩感到快乐,要让他自然健康成长。可快乐算什么东西,生活在Matrix里的人也都快乐呢。活得比较潇洒豁达的人就有资格去嘲笑那些活得很纠结的人,平常人的身份有时候竟然也值得标榜。其实所有时代大概都跟现在一样平庸,只不过这个时代给了平庸的人更多发言的机会。可是啊,不对不对,这些要快乐要豁达的陈腔滥调怎么适合天才呢?我总隐隐约约觉得这个世界上还有天才存在,不然整个世界未免太无趣了一点。所以一般人没资格标榜他们的豁达,他们尚且有能力协调自己与这个世界之间的关系,全然是因为他们根本就没有经受特别大的痛苦,而这痛苦给另外一群人受了。

操作上的困难在于,我自己最多也就算二流的聪明,实在不太容易判断究竟谁是天才。大多神神叨叨的人终归也就只是神神叨叨而已,还有一些是明明天赋不 济却想着要装天才,于是用点神神叨叨去搪塞一部分人的审慎的盘问罢了。他们中的有些人也实在不需要或者说不应该被善待。比如Saraphine同学从前有 着一种一说起感情问题就矫情到要死要活的毛病,开始的时候朋友圈里的人总善意地劝他天涯何处无芳草,长久不见效果只好换个策略,好比拽着衣领狠狠地喊维克 阿普。这哥们后来终于正常了。

我有时候想,何必呢,他显然不是天才,可是身边有个装疯卖傻的人总是件有趣的事情。

也许真正的天才才不会介意我怎么对他呢。

好了,我吐完槽了。看书去了。

Programming, is it still fun for you?

———————————————————————————————————————————

来源:http://www.makinggoodsoftware.com/2009/12/03/programming-is-it-still-fun-for-you/

I am privileged to work on something which I actually enjoy. It is like being a professional sportsman; I get paid to do stuff that I love.

Actually, based on the majority of programmers I know, I would say that most of us feel the same. We are basically a bunch of geeks trying to prove to each other who is a better programmer, we somehow see the day to day in the office as a grown up version of…

<geekstuff>
     <choices>
          <rts>Civilization</rts>
          <mmorpg>World of warcraft</mmrpg>
          <role game>Lord of the rings</ role game>
          <movie>Star wars</movie>
     </choices>
</ geekstuff >

Going to the office is then like a game, and as in any game, if you are not having fun, what´s the point? So, are you still having fun? Having fun at work is, in my opinion, one of the differences that can make a great software developer.

If you are not having fun, you won´t probably be motivated, and if you are not motivated, you are going to do a poor job, so to try to help you, let me present my four golden rules to keep it fun at work!

See your colleagues, and show yourself as a friend, not as a competitor.

Try to avoid getting too emotional when you have arguments with your colleagues as Dale Carnegie said “The only way to get the best of an argument is to avoid it.”

Change your mind set from “what can I do to show they are wrong” to “what can I do to help my colleagues”.

Look for challenges.

Doing easy and repetitive stuff is simply boring.

Don´t take it too seriously, it is only a job.

At the end is only a job, don’t get too stressed if you don’t want to eventually see yourself with an anxiety attack in the office.

If still is not fun, just find another job.

To me not having fun is critical, we expend a huge amount of time at work, so don’t waste it, if you are not having fun just find another job, even if the money is not as good!!!

10+1 things they never teach in college about programming

————————————————————————————————————————

来源:http://www.makinggoodsoftware.com/2010/05/27/10-things-they-never-teach-in-college-about-programming/

I still remember how naive I was just after I finished my studies. I was convinced that I was ready to join any software company and start shining as a top class developer. Obviously, no long after I started working, I realized how many things I didn’t know.

As I have been acquiring experience, I have been learning things the hard way, stuff which I was never taught, and which its understanding, is basic to become a good developer. This is my list of the 10 things I wish I had been taught.

1.- We’re always wrong.

Developers, among other non technical defects, have quite big egos, that´s why is very hard for us to recognize that we were wrong about something. I’ve seen many endless design discussions where developers will go on and on with their own ideas… well, guess what.. We are all wrong, the only difference between our positions is the degree of wrongness.

Is very important to understand and embrace this fact, only once that we do so we will be open to listen to others and use their own ideas to build a better solution.

2.- If something can break, it will break.

Aka “hope driven development“, if you are not sure about something, if you find yourself using the word “should”, then you are in trouble.

There is only one solution for this, do whatever is necessary to make sure that it doesn’t break, this could mean that you will have to write a test, debug, clarify the requirements…

3.- All code is crap.

After 10 years complaining about all the code that surrounds me, I have come to a brilliant conclusion, all code (including mine), is crap. Of course there are many degrees of crappy code, but even the best code I’ve ever seen is not easy to read.

This doesn’t mean that is not worthy trying to make your code better, all the opposite, there’s a huge difference between the best kind of code and the worst kind of code.

4.- There is always a bug.

ALWAYS! Is just a matter of how hard you look for it.

5.- The most important thing is the client.

Among many things the client doesn’t care are: the technologies you use in the project, how many more things that required the application does… or in general, if you use good practices.

And since I can imagine how much hate comments I will get if I only leave the previous paragraph, let me clarify what I want to say… We should never forget the client perspective, sometimes developers use technologies or insist in over engineering just for the sake of using best practices, but remember, if it doesn’t add any value for the client, drop it.

6.- Design on paper doesn’t work.

I used to believe that I could put my whole design in a paper upfront, and then just fill in the gaps, but it simply doesn’t work.

Software development is complex, is hard to see all the entities and their relationships until you don’t get the hands dirty. So keep planning and designing upfront, it is very helpful, just don’t try too hard, and don’t take the diagrams as contracts.

7.- Less is more.

Or as you probably know it better: “Keep it simple, stupid!” (KISS). So if is not necessary drop it, because remember: “If something can break, will break”.

8.- Coding is only 20% of what we do.

Be ready to spent 80% of your time thinking, debugging, testing, in meetings, conversations… And all of the other activities are very important, so you have to develop a wide range of skills, not only technical, to become a good software developer.

9.- The customer doesn’t know what he/she wants NEVER!.

Customers have a necessity, or an idea, but they don’t know the details… Software development is all about discovering the details and removing all the uncertainty and converting them into an application.

10.- Someone has done it before.

So don’t reinvent the wheel, use Google, or better yet, ask your colleagues, many times they may have done already the same or something very similar.

Bonus: Hey! Our job is cool!

On the bright side, programming is still cool!

My ten development principles

——————————————————————————————————————————

来源:http://www.makinggoodsoftware.com/2010/03/13/my-ten-development-principles/

After several years developing software, I have acquired a very a strong opinion on how software should be developed, I actually have come to the conclusion that everything boils down to 10 principles, that if well implemented, will make any software development successful.

1.- Customer first.

“If we don’t take care of the customer… somebody else will.”

Customer first means focusing from a customer perspective on real value for the product being developed, other aspects as: contracts, requirements, technologies… should take a secondary role in the project.

Not focusing on the customer in one the top 5 five non technical mistakes made by programmers.

2.- Code quality.

Even though code quality is something very subjective, (all code is crap), it drives many important aspects as: how hard is to maintain the application or how hard is to take on board a new developer.

In my opinion, the main indicators for code quality are: simplicity, readability, robustness and testability. Other qualities as performance or extensibility, if not required, will over engineer your application.

3.- Empowerment.

People are the most valued resource in software development, not the technologies. They are the ones that make the difference between a mediocre product and an excellent product, but they need to be empowered

Empowerment is the process where people is encouraged to be proactive and take decisions. Some of the most effective mechanisms to empower are: coaching, pairing or delegating.

There is an excellent article from Tony Morgan explaining the difference between a classic delegation approach and empowerment.

empowerment

4.- Continuous integration.

Integration is, from my experience, a major issue in software development. Waiting to integrate at the end of the project or after a big chunk of functionality is completed, is always a traumatic process.

Continuous integration is the process that guarantees that every piece of code committed is automatically integrated in the system. Remember that continuous integration goes beyond continuous compilation.

This article from Martin Fowler, is one of the best references online about continuous integration.

5.- Iterations.

Iterations provide continuous feedback. Continuous feedback is important because it reduces the amount of uncertainty in software development.

While iterations are usually only related to agile methodologies, it is important to remember that there are other methodologies as RUP which also use iterations and they are not part of the agile family.

6.- Automated testing.

Allows refactoring and iterations, provides confidence and if well implemented, enhances the correctness of the final product. To automate tests you may consider some facts about testing and some advices on how to write a good test suite.

7.- Refactoring.

No matter how much care you put on coding, on your first attempt, you are going to be wrong. Refactoring is the practice by which we keep changing the code to meet the changes necessary to introduce in the system.

8.- Informal architecture.

Big design upfront (BDUF), unless you are NASA and can expend 50-60% percent of your project time on it, is a complete waste, but so it is coding without any preparation. Informal architecture is a compromise solution where architecture is discussed in an ongoing basics and is persisted in light documents, boards or similar.

9.- Communication.

Software development is ONLY about communication. The customer explains to the software development team what he wants to accomplish so that the software development team can explain it through code to a computer.

requirements-communication

10.- Avoid waste.

Waste accounts is one of the major productivity killers in software development: unnecessary meetings, unnecessary requirements, unnecessary process, unnecessary documentation, being some of the most common and dangerous.