The 7 Things I Know About Cyber Security After 25 Years | April 2024
Cinci ug-january2011-anti-patterns
1. Anti-Patterns and Worst Practices Steve Smith, MS Regional Director, MVP http://SteveSmithBlog.com | http://CodeProject.com
2. Why Anti-Patterns?Is this just one big rant? You may be wondering What’s in this talk for me? What exactly will I walk away with if I give you an hour of my life?
3. “Those who fail to learn from the mistakes of their predecessors are destined to repeat them” – George Santayana
6. Don’t Repeat YourselfSteve Smith Duplication is waste Repetition in logic calls for abstraction Repetition in process calls for automation …the DRY principle provides fundamental guidance to software developers…
7. Beware the ShareUdiDahan The code review that I had felt so ready for came as a rude awakening — reuse was frowned upon! It turns out that I was missing something critical. Context. The libraries of shared code I created tied the shoelaces of each foot to each other. When applied in the right context, these techniques are valuable. In the wrong context, they increase cost rather than value.
10. Fast Beats Right (FBR)Principle of Mediocre Programming It is always more important to deploy something that appears to work, than to spend time ensuring “correctness” a.k.a. “cowboy coding” or “duct tape programming” It’s OK: When a hard deadline is looming, or for throwaway apps or spikes. Prefer: “Continuous attention to technical excellence and good design enhances agility” – Agile Manifesto
11. Feature CreepPrinciple of Mediocre Programming Projects built using Feature Creep never, ever have release cycles that complete appropriately. Just when the end is in sight, someone adds just one more feature they are desperately in love with. It’s OK: When the added scope is a critical bug fix. Prefer: “Deliver working software frequently, from a couple of weeks to a couple of months, with a preference to the shorter timescale.” – Agile Manifesto
12. Assumption Driven Programming (ADP)Principle of Mediocre Programming Assume the user will only use your software the way you mean for them to. (Psychologists call this false consensus bias.) Of course it should be obvious to anyone how they’re supposed to use the application, so it’s the user’s fault if they do something unexpected.
13. Assumption Driven Programming (ADP)Principle of Mediocre Programming It’s OK: When you are the only user. Prefer: Practice defensive coding. Watch how users attempt to use the software. Treat handling the unexpected like any other feature.
14. Telemarketer Principle (TP)Principle of Mediocre Programming The best way to retain control of what your code does is to manage exactly which objects it uses and what calls it makes at all times. It’s OK: In simple and small applications. Prefer: Follow the Hollywood Principle: “Don’t call us; we’ll call you.” The Dependency Inversion Principle can be used to correct this kind of code.
17. Static Cling Pattern (SCP)Anti-Pattern The easiest way to add functionality or track state is via static/global methods and objects. The Singleton Patternis also your best friend! It’s OK: In simple and small applications. Stateless operations can also be performed via static methods. Prefer: Dependency Inversion Principle. Your code should depend on interfaces, not static calls which cannot be injected. Static methods are death to testable code.
21. Vestigial Structure Pattern (VSP)Anti-Pattern Don’t remove code that’s no longer used just in case it’s needed later! If you’re really brave, comment the code but leave it in there. It’s OK: If you honestly don’t have source control.
22. Vestigial Structure Pattern (VSP)Anti-Pattern Prefer: VSP is often a symptom of a muddled architecture, where it is difficult to tell where one feature begins and another ends. Use source control. Delete unused code; if you end up needing it, recover it from source control.
23. Flags Over Objects (FOO)Anti-Pattern Instead of using objects, polymorphism, or delegation, it’s much faster to just add a flag to a class and expose it. Who needs inheritance? It’s OK: If you are constrained from creating additional child types. Prefer: Tell, Don’t Ask. Instead of checking a flag before performing an action, tell the object what to do and let it polymorphically do so.
26. The God Class (TGC)Anti-Pattern If reuse is good, then reusing one class everywhere in the application is ideal. Strive to create one class to rule them all, capable of doing anything and everything your application might require. It’s OK: In very small applications and spikes. Prefer: Follow the Single Responsibility Principle
28. Found on Internet(FOI)Worst Practice Search engines these days are smart; obviously the first blog post found that appears to solve the issue at hand must be the best approach based on our collective wisdom. Get it to compile and move on. It’s OK: If you really do understand what the code is doing.
29. Found on Internet(FOI)Worst Practice Prefer: Write a spike solution to ensure you understand the code. Write some tests that confirm the code behaves as you expect. Review other approaches – are you asking the right question?
30. Premature Optimization (PO)Worst Practice All code written should be optimized for performance, even if the resulting design is less clear or elegant, or if the code in question is nowhere near the critical path for the application. It’s OK: Optimization is OK when warranted; premature optimization is by definition not OK. Prefer: Define performance requirements. Write tests that validate these requirements are being met. Do not optimize unless these tests fail.Identify bottlenecks; don’t blindly make “fixes”.
31. Copy-Paste-Compile (CPC)Worst Practice The feature you’re working on is nearly identical to one already in the system. Just copy, paste, and get the code to compile and you’re done! It’s OK: In throwaway code (spikes, one-time migration apps, etc.) Prefer: Keep your application code DRY. Refactor common code into shared modules when it makes sense to do so (avoid introducing excessive coupling).
32.
33. Copy Paste Coding Atomiq Wheel View (GetAtomiq.com) Identifies duplicate code Outer ring comprises project files Blue lines are duplicates between files Red lines are duplicates within files
34. Copy Folder Versioning (CFV)Worst Practice When really big changes are imminent, there’s nothing like creating a copy of the current code folder to reassure you that you can always roll back. It’s never OK. USE SOURCE CONTROL
35. Golden Hammer (GH)Worst Practice Your favorite language, framework, library, or tool can do anything! Wield it with confidence, and ignore anybody who tells you another tool might be better suited. It’s OK: When you really do have nails that need hammering. Prefer: Become familiar with a variety of languages, tools, and frameworks. Keep an open mind as you approach problems.
36. Shiny Toy (ST)Worst Practice Did you hear about the latest beta (tool/language/framework)? I’m sure it will solve all of our application’s problems. It’s OK: In spike solutions, and/or for your own learning. Prefer existing and well-known tools and patterns to unproven ones for production use.
37. Reinvent The Wheel (RTW)Worst Practice We can build it better ourselves. No matter what “it” is. We don’t trust anything that was Not Invented Here. It’s OK: When “it” is core to your business and/or application. Prefer: Know and use your application framework (e.g. the .NET framework). Share knowledge within your organization. Learn to make reasonable build vs. buy decisions when appropriate.
38. The Big Ball of Mud Architecture Wins the prize for MOST POPULAR “architecture” By default No clear separation into logical layers
41. Don’t Be Cute With Test DataRod Begbie It was getting late. I was throwing in some placeholder data to test the page layout I'd been working on. I appropriated the members of The Clash for the names of users. Company names? Song titles by the Sex Pistols would do. Now I needed some stock ticker symbols — just some four letter words in capital letters. I used those four letter words. It seemed harmless. Just something to amuse myself, and maybe the other developers the next day before I wired up the real data source. The following morning, a project manager took some screenshots for a presentation...
42. Don’t Build SQL From Untrusted InputsXKCD Wisdom http://xkcd.com/327/
43. Be Mindful of DateTimesXKCD Wisdom Avoid Depending on DateTime.Now Avoid Comparing Times Between Time Zones Don’t Make Assumptions About the User’s Date Format Preferences http://xkcd.com/376/
44. A Few War Stories Some more tales from experienced programmers…
45. Know the PrincipalSteve Smith Who’s Paying For the Project? How directly do you communicate with the stakeholder(s)? Lessons Learned: Be sure you are meeting the needs of the principle. Avoid middlemen if possible. Deliver value early and often. 10 months is way too long to work on a project without a usable release.
46. Premature OptimizationDave Sussman Not just optimized performance… Lesson Learned: Clients don't care about how technically perfect your solution is and you shouldn't focus on the tiny details; get it working first, then refactor if necessary.
47. Ripple LoadingSteve Smith Avoid naïve Active Record pattern Example List Articles Get list of IDs For each ID Fetch the article Fetch the articleContent Fetch the author Lesson Learned: Test with realistic data.
48. Ship “Good Enough”Wally McClure Avoid Analysis Paralysis Build the simplest thing that can work Lessons Learned: Solve the 90% problem first, then solve the next problem, and then the next problem, but don't waste time on a problem to a level that no one really cares about. Startups don't need to spend weeks on a problem that has a simple solution and don't need to overcomplicate the solution.
57. Contact Steve Smith http://SteveSmithBlog.com @ardalis on Twitter ssmith@codeproject.com Dev Resources: http://CodeProject.comAdvertising: http://LakeQuincy.comAgile Dev: http://NimblePros.com
Notes de l'éditeur
We learn from mistakes. Certainly we learn from our own mistakes, but we can also learn from others’ mistakes.George Santayana:“Those who fail to learn from the mistakes of their predecessors are destined to repeat them.” (paraphrased)http://en.wikiquote.org/wiki/George_Santayana
http://en.wikipedia.org/wiki/File:Hindenburg_burning.jpgThis image is a work of a sailor or employee of the U.S. Navy, taken or made during the course of the person's official duties. As a work of the U.S. federal government, the image is in the public domain.
The ceramics teacher announced on opening day that he was dividing the class into two groups. All those on the left side of the studio, he said, would be graded solely on the quantity of work they produced, all those on the right solely on its quality. His procedure was simple: on the final day of class he would bring in his bathroom scales and weigh the work of the "quantity" group: fifty pound of pots rated an "A", forty pounds a "B", and so on. Those being graded on "quality", however, needed to produce only one pot - albeit a perfect one - to get an "A". Well, came grading time and a curious fact emerged: the works of highest quality were all produced by the group being graded for quantity. It seems that while the "quantity" group was busily churning out piles of work - and learning from their mistakes - the "quality" group had sat theorizing about perfection, and in the end had little more to show for their efforts than grandiose theories and a pile of dead clay. Story:http://www.amazon.com/dp/0961454733/Image Licensed with Attribution Required:http://www.flickr.com/photos/jungle_boy/140279885/sizes/o/http://creativecommons.org/licenses/by-nc-sa/2.0/
It was my first project at the company. I'd just finished my degree and was anxious to prove myself, staying late every day going through the existing code. As I worked through my first feature, I took extra care to put in place everything I had learned -- commenting, logging, pulling out shared code into libraries where possible, the works. The code review that I had felt so ready for came as a rude awakening -- reuse was frowned upon!How could this be?The fact that two wildly different parts of the system performed some logic in the same way meant less than I thought. Up until I had pulled out those libraries of shared code, these parts were not dependent on each other. Each could evolve independently. Those four lines of similar code were accidental, a coincidence. That is, until I cam along.
Image is a screenshot from my own email archives.
Show something jury-rigged together with duct tape
See also You are not the User from 97TEPSK.Also known as Programming by Coincidence in The Pragmatic Programmer
See also You are not the User from 97TEPSK.Also known as Programming by Coincidence in The Pragmatic Programmer
Image licensed for sharing with attribution:http://xkcd.com/327/http://creativecommons.org/licenses/by-nc/2.5/
Image licensed for sharing with attribution:http://xkcd.com/376/http://creativecommons.org/licenses/by-nc/2.5/
Photo is owned by speaker.
A couple of years ago, when I was just really starting to do lots more CSS and really didn't know what I was doing, I once spent 2, possibly 3 days, trying to create a single cross browser CSS button with rounded corners; it was an attempt to use the images the designer had supplied for all buttons. I was so focused on getting something clean and elegant and in a single stylesheet, that I completely ignored the fact that it didn't have to be clean, elegant, or in a single stylesheet; it just had to work. The lesson: clients don't care about how technically perfect your solution is and you shouldn't focus on the tiny details; get it working first, then refactor if necessary.
I had a customer that wanted to check addresses. The problem was how would someone handle slight name differences, such as Fort Wayne ad Ft. Wayne, or Elm Street, Elm St. or Elm Str. The PM wanted to create a very big rule based system to check for all kinds of conditions. We were brainstorming and I had a short and simple fix. As I explained it, the PM went off that my solution wasn’t a complete solution. I asked him to give me an example of how it wouldn't work. He couldn't, but he was convinced that there was a problem with my solution. I went ahead and built my solution. He wanted to spend a lot of time (weeks) to solve this one minute problem. Given that this was a startup, I told him that it didn't make sense to spend a lot of time on this problem. I went ahead and built my solution in about 1 hour. Finally, I told him that when he had an address where my solution didn't work, to show it to me and I'd update my code to resolve the issue, but that we needed to move on. Lesson: solve the 90% problem first, then solve the next problem, and then the next problem, but don't waste time on a problem to a level that no one really cares about. Startups don't need to spend weeks on a problem that has a simple solution and don't need to over complicate the solution.
The table has 200,000,000 rows currently · PlacementID ranges from 1 to 5000 and should support at least 50,000 · CreativeID ranges from 1 to 5000 and should support at least 50,000 · PublisherID ranges from 1 to 500 and should support at least 50,000 · CountryCode is a 2-character ISO standard (e.g. ‘US’) and there is a country table with an integer ID already. There are < 300 rows. · RequestedZoneID ranges from 1 to 100 and should support at least 50,000 · AboveFold has values of –1, 0, or 1 only. · Period is a date (no time). · Clicks range from 0 to 5000. · Impressions range from 0 to 5000000. · The table is currently write-mostly. Its primary purpose is to log advertising activity as quickly as possible. Nothing in the rest of the system reads from it except for batch jobs that pull the data into summary tables.