Skip to content

Instantly share code, notes, and snippets.

@fuhoi
Last active March 27, 2019 08:11
Show Gist options
  • Save fuhoi/9affcb1aaf9a11bbd233813a736ce468 to your computer and use it in GitHub Desktop.
Save fuhoi/9affcb1aaf9a11bbd233813a736ce468 to your computer and use it in GitHub Desktop.

Mantras

Some mantras picked up over time.

  • One should double-check one's measurements for accuracy before cutting a piece of wood; otherwise it may be necessary to cut again, wasting time and material.
  • Plan and prepare in a careful, thorough manner before taking action.
  • KISS, an acronym for "keep it simple, stupid", is a design principle noted by the U.S. Navy in 1960.
  • The KISS principle states that most systems work best if they are kept simple rather than made complicated; therefore, simplicity should be a key goal in design, and unnecessary complexity should be avoided.
  • The phrase has been associated with aircraft engineer Kelly Johnson.
  • The term "KISS principle" was in popular use by 1970.
  • Variations on the phrase include: "Keep it simple, silly", "keep it short and simple", "keep it simple and straightforward", "keep it small and simple" and "keep it stupid simple".
  • Single responsibility principle
    • A class should have only a single responsibility, that is, only changes to one part of the software's specification should be able to affect the specification of the class.
  • Open–closed principle
    • Software entities ... should be open for extension, but closed for modification.
  • Liskov substitution principle
    • "Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program." See also design by contract.
  • Interface segregation principle
    • "Many client-specific interfaces are better than one general-purpose interface."
  • Dependency inversion principle
    • One should "depend upon abstractions, not concretions."
  • Don't repeat yourself (DRY, or sometimes do not repeat yourself) is a principle of software development aimed at reducing repetition of software patterns, replacing it with abstractions or using data normalization to avoid redundancy.
  • The DRY principle is stated as "Every piece of knowledge must have a single, unambiguous, authoritative representation within a system".
  • The principle has been formulated by Andy Hunt and Dave Thomas in their book The Pragmatic Programmer.
  • They apply it quite broadly to include "database schemas, test plans, the build system, even documentation".
  • When the DRY principle is applied successfully, a modification of any single element of a system does not require a change in other logically unrelated elements.
  • Additionally, elements that are logically related all change predictably and uniformly, and are thus kept in sync.
  • Besides using methods and subroutines in their code, Thomas and Hunt rely on code generators, automatic build systems, and scripting languages to observe the DRY principle across layers.
  • Worse is better was conceived by Richard P. Gabriel in an essay "Worse is better" to describe the dynamics of software acceptance, but it has broader application.
  • It is the idea that quality does not necessarily increase with functionality.
  • There is a point where less functionality ("worse") is a preferable option ("better") in terms of practicality and usability.
  • Software that is limited, but simple to use, may be more appealing to the user and market than the reverse.
  • 5 Whys is an iterative interrogative technique used to explore the cause-and-effect relationships underlying a particular problem.[1]
  • The primary goal of the technique is to determine the root cause of a defect or problem by repeating the question "Why?".
  • Each answer forms the basis of the next question.
  • The "5" in the name derives from an anecdotal observation on the number of iterations needed to resolve the problem.
  • Not all problems have a single root cause.
  • If one wishes to uncover multiple root causes, the method must be repeated asking a different sequence of questions each time.
  • The method provides no hard and fast rules about what lines of questions to explore, or how long to continue the search for additional root causes.
  • Thus, even when the method is closely followed, the outcome still depends upon the knowledge and persistence of the people involved.
  • The vehicle will not start. (the problem)
  • Why? - The battery is dead. (First why)
  • Why? - The alternator is not functioning. (Second why)
  • Why? - The alternator belt has broken. (Third why)
  • Why? - The alternator belt was well beyond its useful service life and not replaced. (Fourth why)
  • Why? - The vehicle was not maintained according to the recommended service schedule. (Fifth why, a root cause)[2]
  • The premise of the method is that the human brain thinks in a number of distinct ways which can be deliberately challenged, and hence planned for use in a structured way allowing one to develop tactics for thinking about particular issues.
  • De Bono identifies six distinct directions in which the brain can be challenged.
  • In each of these directions the brain will identify and bring into conscious thought certain aspects of issues being considered (e.g. gut instinct, pessimistic judgement, neutral facts).
  • None of these directions is a completely natural way of thinking, but rather how some of us already represent the results of our thinking.
  • Managing Blue – what is the subject? what are we thinking about? what is the goal? Can look at the big picture.
  • Information White – considering purely what information is available, what are the facts?
  • Emotions Red – intuitive or instinctive gut reactions or statements of emotional feeling (but not any justification).
  • Discernment Black – logic applied to identifying reasons to be cautious and conservative. Practical, realistic.
  • Optimistic response Yellow – logic applied to identifying benefits, seeking harmony. Sees the brighter, sunny side of situations.
  • Creativity Green – statements of provocation and investigation, seeing where a thought goes. Thinks creatively, outside the box.
  • The MoSCoW method is a prioritization technique used in management, business analysis, project management, and software development to reach a common understanding with stakeholders on the importance they place on the delivery of each requirement; it is also known as MoSCoW prioritization or MoSCoW analysis.
  • Must have
    • Requirements labeled as Must have are critical to the current delivery timebox in order for it to be a success. If even one Must have requirement is not included, the project delivery should be considered a failure (note: requirements can be downgraded from Must have, by agreement with all relevant stakeholders; for example, when new requirements are deemed more important). MUST can also be considered an acronym for the Minimum Usable SubseT.
  • Should have
    • Requirements labeled as Should have are important but not necessary for delivery in the current delivery timebox. While Should have requirements can be as important as Must have, they are often not as time-critical or there may be another way to satisfy the requirement, so that it can be held back until a future delivery timebox.
  • Could have
    • Requirements labeled as Could have are desirable but not necessary, and could improve user experience or customer satisfaction for little development cost. These will typically be included if time and resources permit.
  • Won't have (this time)
    • Requirements labeled as Won't have have been agreed by stakeholders as the least-critical, lowest-payback items, or not appropriate at that time. As a result, Won't have requirements are not planned into the schedule for the next delivery timebox. Won't have requirements are either dropped or reconsidered for inclusion in a later timebox. (Note: occasionally the term Would like to have is used; however, that usage is incorrect, as this last priority is clearly stating something is outside the scope of delivery).
  • T-shirt sizing is a way to practice relative sizing.
  • By comparing stories, you can break them into buckets of extra-small, small, medium, large, and extra-large.
  • Estimating in relative buckets is more important than estimating absolute time or effort.
  • We want to understand how things compare to each other in a rough sense, and not waste time on false precision.
  • Organizations which design systems are constrained to produce designs which are copies of the communication structures of these organizations.
  • The law is based on the reasoning that in order for a software module to function, multiple authors must communicate frequently with each other.
  • Therefore, the software interface structure of a system will reflect the social boundaries of the organization(s) that produced it, across which communication is more difficult.
  • Conway's law was intended as a valid sociological observation, although sometimes it's used in a humorous context.
  • An expression critical of committees—or by analogy, group decision-making—by emphasizing the ineffectiveness of incorporating too many conflicting opinions into a single project through compromise.
  • In this figure of speech, the distinguishing features of a camel, such as its humps and poor temperament, are taken to be the deformities that resulted from its poor design.
  • If too many people participate in a task, the task will not be done very well.
  • Always implement things when you actually need them, never when you just foresee that you need them.
  • Martin Fowler - Yagni
  • Chartjunk refers to all visual elements in charts and graphs that are not necessary to comprehend the information represented on the graph, or that distract the viewer from this information.
  • The Pit of Success: in stark contrast to a summit, a peak, or a journey across a desert to find victory through many trials and surprises, we want our customers to simply fall into winning practices by using our platform and frameworks. To the extent that we make it easy to get into trouble we fail.
  • Your language isn't broken, it's doing floating point math.
  • Computers can only natively store integers, so they need some way of representing decimal numbers.
  • This representation comes with some degree of inaccuracy.
  • That's why, more often than not, .1 + .2 != .3.
  • It's actually pretty simple. When you have a base 10 system (like ours), it can only express fractions that use a prime factor of the base. The prime factors of 10 are 2 and 5. So 1/2, 1/4, 1/5, 1/8, and 1/10 can all be expressed cleanly because the denominators all use prime factors of 10.
  • In contrast, 1/3, 1/6, and 1/7 are all repeating decimals because their denominators use a prime factor of 3 or 7. In binary (or base 2), the only prime factor is 2. So you can only express fractions cleanly which only contain 2 as a prime factor. In binary, 1/2, 1/4, 1/8 would all be expressed cleanly as decimals. While, 1/5 or 1/10 would be repeating decimals.
  • So 0.1 and 0.2 (1/10 and 1/5) while clean decimals in a base 10 system, are repeating decimals in the base 2 system the computer is operating in.
  • When you do math on these repeating decimals, you end up with leftovers which carry over when you convert the computer's base 2 (binary) number into a more human readable base 10 number.
  • Date: 2019-03-27
    • YYYY-MM-DD or YYYYMMDD
  • Date and time in UTC
    • 2019-03-27T02:32:53+00:00
    • 2019-03-27T02:32:53Z
    • 20190327T023253Z
    • hh:mm:ss.sss or hhmmss.sss
    • hh:mm:ss or hhmmss
    • hh:mm or hhmm
    • Timezone: Z or +hh:mm or +hhmm or +hh
  • Duration
    • P[n]Y[n]M[n]DT[n]H[n]M[n]S
    • P3Y6M4DT12H30M5S represents a duration of "three years, six months, four days, twelve hours, thirty minutes, and five seconds".
  • Date and time values are ordered from the largest to smallest unit of time: year, month (or week), day, hour, minute, second, and fraction of second. The lexicographical order of the representation thus corresponds to chronological order, except for date representations involving negative years. This allows dates to be naturally sorted by, for example, file systems.
  • Each date and time value has a fixed number of digits that must be padded with leading zeros.
  • Representations can be done in one of two formats – a basic format with a minimal number of separators or an extended format with separators added to enhance human readability. The standard notes that "The basic format should be avoided in plain text." The separator used between date values (year, month, week, and day) is the hyphen, while the colon is used as the separator between time values (hours, minutes, and seconds). For example, the 6th day of the 1st month of the year 2009 may be written as "2009-01-06" in the extended format or simply as "20090106" in the basic format without ambiguity.
  • For reduced accuracy, any number of values may be dropped from any of the date and time representations, but in the order from the least to the most significant. For example, "2004-05" is a valid ISO 8601 date, which indicates May (the fifth month) 2004. This format will never represent the 5th day of an unspecified month in 2004, nor will it represent a time-span extending from 2004 into 2005.

CleanArchitecture

  • Independent of Frameworks.
    • The architecture does not depend on the existence of some library of feature laden software.
    • This allows you to use such frameworks as tools, rather than having to cram your system into their limited constraints.
  • Testable.
    • The business rules can be tested without the UI, Database, Web Server, or any other external element.
  • Independent of UI.
    • The UI can change easily, without changing the rest of the system.
    • A Web UI could be replaced with a console UI, for example, without changing the business rules.
  • Independent of Database.
    • You can swap out Oracle or SQL Server, for Mongo, BigTable, CouchDB, or something else.
    • Your business rules are not bound to the database.
  • Independent of any external agency.
    • In fact your business rules simply don’t know anything at all about the outside world.
  • The Dependency Rule
    • The concentric circles represent different areas of software.
    • In general, the further in you go, the higher level the software becomes.
    • The outer circles are mechanisms.
    • The inner circles are policies.
    • This rule says that source code dependencies can only point inwards.
    • Nothing in an inner circle can know anything at all about something in an outer circle.
    • In particular, the name of something declared in an outer circle must not be mentioned by the code in the an inner circle.
    • That includes, functions, classes, variables, or any other named software entity.
  • Entities
    • Entities encapsulate Enterprise wide business rules.
    • An entity can be an object with methods, or it can be a set of data structures and functions.
    • It doesn’t matter so long as the entities could be used by many different applications in the enterprise.
  • Use Cases
    • The software in this layer contains application specific business rules.
    • It encapsulates and implements all of the use cases of the system.
    • These use cases orchestrate the flow of data to and from the entities, and direct those entities to use their enterprise wide business rules to achieve the goals of the use case.
  • Interface Adapters
    • The software in this layer is a set of adapters that convert data from the format most convenient for the use cases and entities, to the format most convenient for some external agency such as the Database or the Web.
    • It is this layer, for example, that will wholly contain the MVC architecture of a GUI.
    • The Presenters, Views, and Controllers all belong in here.
    • The models are likely just data structures that are passed from the controllers to the use cases, and then back from the use cases to the presenters and views.
  • Frameworks and Drivers.
    • The outermost layer is generally composed of frameworks and tools such as the Database, the Web Framework, etc.
    • Generally you don’t write much code in this layer other than glue code that communicates to the next circle inwards.
    • By the same token, data formats used in an outer circle should not be used by an inner circle, especially if those formats are generate by a framework in an outer circle.
    • We don’t want anything in an outer circle to impact the inner circles.

The mythical man-month

  • Brooks discusses several causes of scheduling failures. The most enduring is his discussion of Brooks's law: Adding manpower to a late software project makes it later.
  • Man-month is a hypothetical unit of work representing the work done by one person in one month; Brooks' law says that the possibility of measuring useful work in man-months is a myth, and is hence the centerpiece of the book.
  • Complex programming projects cannot be perfectly partitioned into discrete tasks that can be worked on without communication between the workers and without establishing a set of complex interrelationships between tasks and the workers performing them.
  • Therefore, assigning more programmers to a project running behind schedule will make it even later.
  • This is because the time required for the new programmers to learn about the project and the increased communication overhead will consume an ever increasing quantity of the calendar time available.
  • When n people have to communicate among themselves, as n increases, their output decreases and when it becomes negative the project is delayed further with every person added.
  • Group intercommunication formula: n(n − 1) / 2
  • Example: 50 developers give 50 · (50 – 1) / 2 = 1225 channels of communication.

No silver bullet

  • Brooks insists that there is no one silver bullet -- "there is no single development, in either technology or management technique, which by itself promises even one order of magnitude [tenfold] improvement within a decade in productivity, in reliability, in simplicity."
  • The argument relies on the distinction between accidental complexity and essential complexity, similar to the way Amdahl's law relies on the distinction between "strictly serial" and "parallelizable".

The second-system effect

  • The second-system effect proposes that, when an architect designs a second system, it is the most dangerous system they will ever design, because they will tend to incorporate all of the additions they originally did not add to the first system due to inherent time constraints.
  • Thus, when embarking on a second system, an engineer should be mindful that they are susceptible to over-engineering it.

The tendency towards irreducible number of errors

  • The author makes the observation that in a suitably complex system there is a certain irreducible number of errors.
  • Any attempt to fix observed errors tends to result in the introduction of other errors.

Progress tracking

  • Brooks wrote "Question: How does a large software project get to be one year late? Answer: One day at a time!"
  • Incremental slippages on many fronts eventually accumulate to produce a large overall delay.
  • Continued attention to meeting small individual milestones is required at each level of management.

Conceptual integrity

  • To make a user-friendly system, the system must have conceptual integrity, which can only be achieved by separating architecture from implementation.
  • A single chief architect (or a small number of architects), acting on the user's behalf, decides what goes in the system and what stays out.
  • The architect or team of architects should develop an idea of what the system should do and make sure that this vision is understood by the rest of the team.
  • A novel idea by someone may not be included if it does not fit seamlessly with the overall system design.
  • In fact, to ensure a user-friendly system, a system may deliberately provide fewer features than it is capable of.
  • The point being, if a system is too complicated to use, many features will go unused because no one has time to learn them.

The manual

  • The chief architect produces a manual of system specifications.
  • It should describe the external specifications of the system in detail, i.e., everything that the user sees.
  • The manual should be altered as feedback comes in from the implementation teams and the users.

The pilot system

  • When designing a new kind of system, a team will design a throw-away system (whether it intends to or not).
  • This system acts as a "pilot plan" that reveals techniques that will subsequently cause a complete redesign of the system.
  • This second, smarter system should be the one delivered to the customer, since delivery of the pilot system would cause nothing but agony to the customer, and possibly ruin the system's reputation and maybe even the company.

Formal documents

  • Every project manager should create a small core set of formal documents defining the project objectives, how they are to be achieved, who is going to achieve them, when they are going to be achieved, and how much they are going to cost.
  • These documents may also reveal inconsistencies that are otherwise hard to see.

Project estimation

  • When estimating project times, it should be remembered that programming products (which can be sold to paying customers) and programming systems are both three times as hard to write as simple independent in-house programs.
  • It should be kept in mind how much of the work week will actually be spent on technical issues, as opposed to administrative or other non-technical tasks, such as meetings, and especially "stand-up" or "all-hands" meetings.

Communication

  • To avoid disaster, all the teams working on a project should remain in contact with each other in as many ways as possible—e-mail, phone, meetings, memos etc.
  • Instead of assuming something, implementers should ask the architect(s) to clarify their intent on a feature they are implementing, before proceeding with an assumption that might very well be completely incorrect.
  • The architect(s) are responsible for formulating a group picture of the project and communicating it to others.

The surgical team

  • Much as a surgical team during surgery is led by one surgeon performing the most critical work, while directing the team to assist with less critical parts, it seems reasonable to have a "good" programmer develop critical system components while the rest of a team provides what is needed at the right time.
  • Additionally, Brooks muses that "good" programmers are generally five to ten times as productive as mediocre ones.

Code freeze and system versioning

  • Software is invisible.
  • Therefore, many things only become apparent once a certain amount of work has been done on a new system, allowing a user to experience it.
  • This experience will yield insights, which will change a user's needs or the perception of the user's needs.
  • The system should, therefore, be changed to fulfill the changed requirements of the user.
  • This can only occur up to a certain point, otherwise the system may never be completed.
  • At a certain date, no more changes should be allowed to the system and the code should be frozen.
  • All requests for changes should be delayed until the next version of the system.

Specialized tools

  • Instead of every programmer having his own special set of tools, each team should have a designated tool-maker who may create tools that are highly customized for the job that team is doing, e.g., a code generator tool that creates code based on a specification. In addition, system-wide tools should be built by a common tools team, overseen by the project manager.

Lowering software development costs

  • There are two techniques for lowering software development costs that Brooks writes about:
  • Implementers may be hired only after the architecture of the system has been completed (a step that may take several months, during which time prematurely hired implementers may have nothing to do).
  • Another technique Brooks mentions is not to develop software at all, but simply to buy it "off the shelf" when possible.

Quotes

  • "Don't hate the player, hate the game."
  • "Fudge factor."
  • "Disk is cheap."
  • "Refactoring has a high risk without proper testing."
  • "I haven't yet met anyone who's had enough experience with it to hate it yet."
  • "In carpentry you measure twice and cut once. In software development you never measure and make cuts until you run out of time."
  • "Software being 'Done' is like lawn being 'Mowed'."
  • "A computer is like a mischievous genie. It will give you exactly what you ask for, but not always what you want."
  • "If you say "I told you so", you are the one who has failed. Because you knew, but did not manage to stop the train wreck."
  • "An evolving system increases its complexity unless work is done to reduce it."
  • "90% of the functionality delivered now is better than 100% delivered never."
  • "The best way to get the right answer on the internet is not to ask a question; it's to post the wrong answer."
  • "A good API is not just easy to use but also hard to misuse."
  • "(...) Thinking this way will teach you two things about computers: One, there’s no magic, no matter how much it looks like there is. There’s just work to make things look like magic. And two, it’s crazy in there."
  • "A person without data is just another person with an opinion."

Resources

@fuhoi
Copy link
Author

fuhoi commented Mar 27, 2019

CleanArchitecture

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment