Photo
Waterfall 2018 Christmas Special!
Happy Christmas and a successful New Year to all our clients from BashCorp 😊
0 notes
Text
Code Extensibility
Another little snippet on code standards to help make code better!
Coding or Extensibility of one of the goals of the SOLID development pillars:
Single Responsibility Principle
Open-Closed Principle
Liskov Substitution Principle
Interface Segregation Principle
Dependency Injection Principle
These principles are designed to lead to code that is easily extendable, easily tested and localises changes to one place in the code-base.
What is code extensibility?
Simply, the ability to take an existing piece of logic and use it to solve a problem without copy-pasting (and creating duplicate code, with its associated maintenance overhead) and without breaking things the code already does.
Consider a function that adds up two numbers. We may want to extend it so it can cope with adding negative numbers also, but we don't want to break it so it no longer adds positive numbers and we don't want to write another 'Add' function.
Single Responsibility Principle
To keep code extensible, testable and readable (lean) we should consider the Single Responsibility Principle. A piece of code should do one thing and do that one thing well.
A function that adds up should do adding, it shouldn't also do multiplication. A class that reads customers from a database shouldn't also write out HTTP cookies. A namespace for Validation shouldn't also handle CRM/Sitecore integration.
SRP keeps code lean, focused and more easily understandable.
Open-Closed Principle
Code should be open for extension and closed for modification. This is a principle focused on adding new features without breaking what's there.
If a new use-case appears that involves changes to code, eg maybe business customers get a different discount process than home customers, then we should leave the existing logic alone.
This will prevent our breaking things for existing customers and processes.
We can then extend the existing logic using normal Object-Oriented inheritance, functional-style Composition or amendments to our IoC container to build this new logic.
For example, if we have a PurchaseDiscount class we might inherit from it to create BusinessPurchaseDiscount and HomePurchaseDiscount. That way, anywhere in the code still using PurchaseDiscount will be unaffected and the system will not break. It keeps regression errors to a minimum.
We can then, at our leisure, update the code to use the new extended code to implement the new behaviour.
Liskov Substitution Principle
This rule states that wherever a parent class is used, an inheriting class should be able to be substituted without breaking the system.
Supposing I have a class that calculates BasketTotal. It takes an array of items and calculates their prices. Suppose then that we inherit from it to create BusinessBasketTotal that calculates prices and applies a business discount.
Anywhere I use BasketTotal, I should in theory be able to substitute BusinessBasketTotal. However, if BasketTotal has a property float total and BusinessBasketTotal implements its own BusinessTotal and overrides the total property from its parent and always returns -1 instead of the total, then this would break the Liskov Substitution principle.
public class BasketTotal { public float Total { get; private set; }
public virtual void Sum(BasketItem[] items) { Total = 0f; foreach(var item in items) { Total += item.Price; } } }
public class BusinessBasketTotal : BasketTotal { // Don't need this because it's a business basket? public override float Total => -1f; // Return a business basket total instead public float BusinessTotal {get; private set; }
public virtual void Sum(BasketItem[] items) { BusinessTotal = 0f; foreach(var item in items) { BusinessTotal += item.BusinessPrice; } } }
It would not be possible to use BusinessBasketTotal in place of BasketTotal because the former breaks the design of the latter by returning a -1 for price.
This is a bad idea because it's likely to lead to weird behaviour in the system: .Net will happily allow BusinessBasketTotal in place of BasketTotal, but that will break our logic. What should be done instead is to have BusinessBasketTotal respect the interface set out in BasketTotal and set the Total property correctly.
Interface Segregation Principle
An important part of being able to compose objects together to solve bigger problems is being able to refer to them by interface. Interfaces offer advantages to the traditional inheritance model of OO software, behaving more like interchangeable Lego bricks.
If you want a class to do something different in place of another, write a new class that implements the same interface and use it instead.
This leaves an important design consideration when planning interfaces: keep them focused and not too big. It closely relates to the Single Responsibility Principle.
Let's say I have a ICustomerSaver, an interface that has the sole purpose of persisting a customer object to storage somewhere. If I write a class to implement that interface, I'd expect to write methods like Save.
Supposing I implement that interface in my class, and I am asked to write methods for Serialize, GetFromDB or CheckOrders. What has happened is that this interface does not follow the good design principle of Interface Segregation.
I implemented the ICustomerSaver interface because I wanted a class that could save Customer objects in a new way- I should not be implementing serialisation, database access or order management methods. They should be separate interfaces (eg ISerializable, IDbAccess and IOrderManager) that I choose to implement if I need them.
Dependency Injection Principle
The final step for extensible, readable and testable code is the Dependency Injection Principle. This means that if I have one class that depends on another for its logic, then that dependency should be passed in (ie injected).
public class CustomerManager { public void Save(Customer customer) { var database = new CustomerDatabase(); database.Persist(customer); } }
Consider the class above if we make changes to the CustomerDatabase object. Perhaps we add some constructor parameters, or want to replace it with a different class. We've now made a lot of work for ourselves if we want to make such changes because we'll need to change every place we use CustomerDatabase.
Suppose, instead, we injected it as a dependency:
public class CustomerManager { public void Save(Customer customer, CustomerDatabase database) { database.Persist(customer); } }
That's better: now it is the responsibility of whatever uses CustomerManager to supply the CustomerDatabase object as an argument. Presumably that will be down much farther up the stack, so there will be fewer places to change it if CustomerDatabase changes.
However, we can do better. CustomerManager is likely to have several methods, for example Save and Load. We could then pass CustomerDatabase as a constructor argument rather than as a method argument:
public class CustomerManager { private CustomerDatabase database;
public CustomerManager(CustomerDatabase database) { this.database = database; }
public void Save(Customer customer) { database.Persist(customer); }
public Customer Load(Guid customerId) { return database.Find(customerId); } }
So we have now reduced duplication and followed better Single Responsibility: the constructor gathers dependencies and then individual methods use them to solve specific problems.
However, we still have the issue of changes to CustomerDatabase: supposing we follow the Open for Extension Principle and create a new database layer that we now want to use here? We must manually find and replace all CustomerDatabase instances with our new PersonDatabase object.
We can solve this by using Interfaces for our dependency injection. Consider:
public interface ICustomerPersistence { Customer Find(Guid customerId); void Save(Customer customer); }
public class CustomerManager { private ICustomerPersistence database;
public CustomerManager(ICustomerPersistence database) { this.database = database; }
public void Save(Customer customer) { database.Persist(customer); }
public Customer Load(Guid customerId) { return database.Find(customerId); } }
Now CustomerManager will accept, without any changes whatsoever, any ICustomerPersistence implementer we choose to pass to it.
Using an IoC container (such as Unity, StructureMap, Ninject, AutoFaq or many others) we can even automate this in code, eg:
container.Register<ICustomerPersistence, PersonDatabase>(); container.Register<CustomerManager, CustomerManager>(); // ... var customerManager = container.Get<CustomerManager>(); // This will now work with everything done for us: customerManager.Load(customerId);
The IoC container will create a CustomerManager and, as long as it knows what to use for a ICustomerPersistence it will handle running the constructor for us. Swapping out to a different database is now a simple matter of writing a new class that implements ICustomerPersistence and changing that one line in the container registry!
0 notes
Text
Free PDF eBook: Web UX Guide!
From our co-director, Kaylee (Grand Clarity), this is a free copy of her Web UX guide!
Download here! or Buy on Amazon for Kindle
0 notes
Photo

When talking with clients about UK GDPR regulations...
0 notes
Text
Coding for Performance
Some more tricks-and-tips from BASHCorp for making your .Net app better!
Database Queries
Consider using the SQL Server Performance Monitor, or just analysing your query with the Query Analyser tool.
The latter is great at suggesting new indices that can speed up the query.
Note that for LINQ-to-SQL, you can use a tool like Glimpse to see what database queries LINQ is building. LINQ tries its best but it doesn't always get things right.
Repetition, Loops, Repetition, LINQ and Repetition
Whenever you're looping over something, be it through a while-loop, a LINQ expression or just calling the same method lots and lots, consider how you might be able to improve efficiency.
For example: Is your loop creating a new complex orchestrator/manager object each time? If so, create one outside the loop and use that.
String+concatenation
If you're building a string by joining together lots of small strings, use the .Net System.Text.StringBuilder class. It's designed to work efficiently, whereas string + string will (due to string being immutable) create a new string each time and, until the Garbage Disposal runs, those strings will start filling up memory.
Disposable
When you use a class that implements IDisposable (such as StreamReader) you should put it in a using(){} block to ensure that it is correctly disposed of once you're done with it. This frees up memory and resources.
Similarly, if you write a class that makes heavy use of memory or creates dependencies that need to be closed-down and removed once the class has served its purpose, you should implement IDisposable correctly.
.Net Garbage Disposal
The .Net GD is generally tuned well. Don't mess with it unless you know what you're doing. If you need to trigger it to collect all unused/finalised objects and free their memory then you can access it using GC.Trigger();.
Static Methods
A static method is shared across all instances of a class. In theory this means a static method might be more efficient. Only use static methods where the method does not interact with the state of the object: if its reading class-level variables, properties or whatever then it's not static.
Static methods are not, naturally, thread safe
Threads and Thread-Safety
You can improve efficiency by allowing .Net and the Just in Time Optimiser (JIT) to parallelise some tasks. You can use several tools in the System.Threading.Tasks.Parallel class (such as Parallel.ForEach) to improve efficiency.
Alternatively you can implement awaitable methods, which do not block execution whilst waiting for resources.
Finally you can create your own threads to background an operation and allow the code to continue until the thread returns. Generally use the QueueUserWorkItem method to allow the runtime to schedule your thread most effectively.
Release Mode vs. Debug Mode
One of the biggest changes in Visual Studio/MSBuild build modes is Release vs. Debug, and that huge change is very small: release mode sets the 'optimize' flag to true, whereas debug does not.
With the optimise bit enabled, the .Net runtime and the Just-In-Time Compiler (colloquially called the JIT'ter) will make your code as efficient as possible on-the-fly. Methods might be inlined, methods might be cached or pre-compiled from IL to machine-code for performance. It's absolute magic written by some extremely clever people.
0 notes
Text
Coding for Security!
A little primer with some basic stuff on coding for security.
Software security is an enormous topic. As a short reminder, always consider STRIDE when you are writing your code and consider whether what you're doing is vulnerable to a STRIDE category:
S: Spoofing
Spoofing means to pretend to be someone you are not.
Example:
1. Read PERSONID from query string 2. Check CRM for Person record 3. Display record In this example, there is no check to confirm that the current user is the person whose record is being retrieved. It relies only on the PERSONID passed in. This means anyone can guess PERSONIDs until they get one that works.
Solution:
1. Read PERSONID from query string 2. Read PERSONID of currently logged in user 3. If not logged in, or not matching PERSONID, then deny request. 4. Else, check CRM and display record Always check the user is who they say they are.
T: Tampering
Tampering means altering information to try and crack the system.
Example:
1. Read shopping cart from user's POST 2. Charge user for total price stored in shopping cart 3. On success, confirm sale. In this example, a malicious user could easily change the shopping cart data being posted to the server (perhaps amending hidden fields using their browser's DevTools, or crafting a request in Postman or Fiddler) and give themselves a hefty discount.
Solution:
1. Read shopping cart from user's POST 2. Retrieve shopping cart item prices from stock control system 3. Calculate total price based on data from stock control 4. Charge user for total price 5. On success, confirm sale Confirm data is correct against relevant systems once received from user
R: Repudiation
Repudiation means to plausibly deny that something happened. If I steal your lunch, and you accuse me of doing so without proof, then I can repudiate your accusation by denying it happened.
Example:
In a routine business-as-usual activity, we notice a purchase record that shows a customer has received thousands of pounds worth of training for a substantially low price. When confronted, the customer denies all knowledge of wrongdoing and claims they purchased the training legitimately. IT check their transaction logs and find no information at all to confirm or deny wrongdoing, so the matter must be dropped.
In this example, we are confident that a malicious user has done something to crack our systems and fraudulently buy training at a huge discount. However, because there are insufficient logs in place, we cannot confirm or deny what happened so our response to the malicious activity is very limited.
Solution:
A customer notices that they can tamper with data on an ordering form and add in a large discount. Luckily, the shopping cart was logged in our transaction history. Further more, the response from the user was also logged in our web server and in our rolling code log. When the fraud is noticed, we can compare the purchase record with the shopping cart log, the web server log and the rolling code log. We can see that the user has changed the shopping cart by adding in a discount. We now have non-repudiation and can take appropriate action.
Log transactional data: what happened, when and by whom.
I: Information Disclosure
Information disclosure relates to giving away clues or details that the user has not authenticated themselves to retrieve.
Example:
A malicious user is trying to crack the administrator account. They do not know the username, or the password. They first try 'administrator' and 'password'. The system returns an error, stating "User not found." Next they try 'admin' and 'password'. This time the system returns an error saying 'Password incorrect'. The malicious user now knows the user name is 'admin' and is 50% of the way to breaking in to the system.
In this example, the error messages returned by the system are trying to be helpful and user-friendly. Unfortunately, in trying to be helpful, they are revealing more than they should. They allow a malicious user to identify when they have correctly guessed a user name, rather than remaining vague over whether user name or password is the mistake.
Solution:
A malicious user is trying to crack the administrator account. They do not know the username, or the password. They first try 'administrator' and 'password'. The system returns an error, stating "User name or password incorrect." They must now try every combination of user name and password to find the credentials.
Don't give out more information that is more sensitive than that which the user has given to you
D: Denial of Service
A denial of service attack (and its variants) involves hammering a system to take advantage of it or to render it unusable for others.
Example:
A malicious user wants to see what will happen if they DoS the Billing Information screen in a web system. They set up a script to hit the page thousands of times a second. This causes a race-condition in the code that returns another user's data on the billing screen and results in a Data Protection breach.
Often, DoS attacks are about simply slowing or crashing a system to be an inconvenience or for blackmail. However, it may also be a technique used by crackers to access data: DoS puts the target system into an exceptional state, where it may behave unexpectedly. Race conditions may occur, memory overflows could happen, methods that are not thread-safe may overwrite one another. In these situations, the attackers may be able to steal valuable data or gain knowledge about the inner workings of the system.
Solution:
A malicious user wants to see what will happen if they DoS the Billing Information screen in a web system. They set up a script to hit the page thousands of times a second. The server begins dropping their connections, since it detects a flood of requests, to prevent the system from being overloaded. The malicious user gets nothing but status code '429 Too Many Requests' back.
Be aware of edge cases and exceptional circumstances, and how they can be mitigated
E: Elevation of Privilege
Elevation of Privilege is similar to Spoofing, but in this circumstance the user has authenticated themselves accurately and been legitimately allowed into the system. However, they have since found a way to gain additional powers beyond those granted to them based on their credentials.
Example:
A user logs in to an online message board. They notice that there are standard users, of which they are a member, and that there are administrators with additional powers. As a guess, the user tries changing the address in their web browser to include '?admin=true' and they suddenly find all the administrative functions are available to them.
This example shows that a user with a particular role can gain access to elevated powers. This user can now act as an administrator and do whatever that role permits them to do.
Solution:
A user logs in to an online message board. They notice that there are standard users, of which they are a member, and that there are administrators with additional powers. As a guess, the user tries changing the address in their web browser to include '?admin=true'. The system shows them a screen which reads 'Forbidden'.
What should be done in this circumstance is to check the role of the authenticated user against the action they are trying to perform and only allow it if their role permits it.
Gatekeep power-user/admin functions with role-based controls
Summary
The STRIDE methodology is not exhaustive, but provides a useful framework for thinking about how a system may be compromised. Solutions are also not mutually exclusive, for example Elevation of Privilege can be mitigated by role based access + logging, Tampering can be mitigated by logging + encryption.
Common themes when developing secure .Net applications are:
Digitally sign assemblies so they cannot be altered
Run code with the minimum viable privilege (eg NetworkUser)
Use SSL/TLS at application boundaries (eg on SOAP endpoints)
Check roles before allowing a user to perform an action
Log transactions, with details of what happened, when and who did it
Encrypt data when it travels across application boundaries to prevent changes
Don't give out more sensitive data then the user has provided
Consider rate-limiting or throttling requests, at either server or code level.
Check credentials before displaying sensitive data
Confirm back-end system data to prove it has not been altered.
Specific Security Vulnerabilities
In addition to the general STRIDE principals, it is useful to have a grasp of some of the more common exploits that malicious users might try to implement.
Cross-site scripting vulnerabilities (XSS)
This is when a malicious user is able to inject content (usually JavaScript) into a page. Common vectors for this are comment fields, message board-style systems and anything allowing file upload. Rich text fields are also a vector.
Most .Net frameworks (WebForms and MVC) make it intentionally difficult to allow a user to upload scripts and then have those scripts displayed raw back on the site to prevent this.
See also: RequestPathInvalidCharacters, RequestValidationMode and RequestValidationType.
SQL Injection
Often an application will take input from the user and then use that to query a database. Care must be taken that, where user input is sent down to the database, that their input is correctly parameterised (or 'escaped' in PHP parlance).
Most ORM and DataAccess frameworks (EntityFramework, EnterpriseLibrary, ADO.Net but not dapper) do this by default, although you can explicitly code it if you want.
Without correctly parameterised user input, a user could potentially write SQL code and have that executed on the database- revealing sensitive data or just dropping an entire table.
0 notes
Text
Windows 95 Theme for Windows 10
Yes, roll up roll up! You can relive the glory days of Windows 95 with this free theme for Windows 10 😊 includes a Windows 95 inspired set of desktop icons, wallpaper and start menu for Classic Shell with the original sounds!
https://github.com/ke2083/Windows95Theme
2 notes
·
View notes
Text
C#: A Simple Guide for Simple Developers
Since we were (and in my case, still are!) simple developers, I wrote this walkthrough for friend who was starting his engineering MSc. and needed a grounding in C#. It’s by no means complete but it’s basically all there and covers everything from absolute beginner.
Download from GitHub
0 notes
Photo

Waterfall Christmas 2017
Amalgamated Biscuits and Fluff Inc. (a division of GloboDynamix Weapons Systems) is the setting for our heroes: Goto Soon, the senior developer and his friends Sheepish and Zub. Waterfall is the story of their struggles against the forces out to ensure they never complete a software project again: their boss Machiovelle O’Puss, Stu Bunn (the project manager pig), The Marketing Peacock, Kevin The Surprisingly Senior Inefficiency Beetle, and a cast of other lunatics!
Based on true events.
Transcript:
Waterfall, by Kaylee and Cloud.
Caption: unfortunately it was the dev team’s turn to organise secret Santa that year...
The developers, Zub; Goto; Kevin the Surprisingly Senior Inefficiency Beetle and Sheepish, are hard at work over engineering a ridiculously convoluted system that is, presumably, something to do with secret Santa. Sheepish is asking “So, did we ever decide on TDD or BDD for our unit tests?”
0 notes
Photo

Waterfall #5: The Interview
Amalgamated Biscuits and Fluff Inc. (a division of GloboDynamix Weapons Systems) is the setting for our heroes: Goto Soon, the senior developer and his friends Sheepish and Zub. Waterfall is the story of their struggles against the forces out to ensure they never complete a software project again: their boss Machiovelle O’Puss, Stu Bunn (the project manager pig), The Marketing Peacock, Kevin The Surprisingly Senior Inefficiency Beetle, and a cast of other lunatics!
Based on true events.
Transcript:
6 months ago, Goto Soon is in a job interview with Stuart Bunn (Project Pig).
Stu: Yes, we've been agile for some time now.
Goto: That's great, which methodology are you using?
Stu: The one with those daily stands in the morning!
Goto: Right...
Stu: I love those meetings! It really sets me up for the day to know that everybody's following the Master Plan I create at the beginning of the project.
Goto: Um...
Stu: It also stops me going all day without standing up! After my ninth DVT it was a literal lifesaver. Between that, and donuts on Fridays, and the Master Plan I've pretty much conquered IT management! My CV is like a credit card I never have to pay off!
Machiovelle O'Puss (Dept. Head): Tell them about the Gantt charts!
Goto: Er, thanks guys. I'll let you know...
Cut to present day. Goto is at the morning standup with Kevin (the Surprisingly Senior Inefficiency Beetle) and Sheepish. Stuart is taking his seat.
Goto: Lousy weak economy...
0 notes
Photo

Waterfall Short #3: Field Guide to Your Colleagues- Zub the Development Magpie
Oh, Zub. He means well and has so much enthusiasm... unfortunately none of it for writing useful code that will actually ship! The grass is always greener in another GitHub project. Whatever tool the system is currently built in, it's out of date. Any problems you have, they'll be solved by rewriting it a different way. He's rewritten the code in almost every framework there is, and never shipped any of them. He's a lovable scamp, and infuriatingly flighty. We're not sure, but despite being a bee we think he was raised by magpies.
Amalgamated Biscuits and Fluff Inc. (a division of GloboDynamix Weapons Systems) is the setting for our heroes: Goto Soon, the senior developer and his friends Sheepish and Zub. Waterfall is the story of their struggles against the forces out to ensure they never complete a software project again: their boss Machiovelle O’Puss, Stu Bunn (the project manager pig), The Marketing Peacock, Kevin The Surprisingly Senior Inefficiency Beetle, and a cast of other lunatics!
Based on true events.
0 notes
Photo

Waterfall #4: The Return of the Marketing Peacock
Amalgamated Biscuits and Fluff Inc. (a division of GloboDynamix Weapons Systems) is the setting for our heroes: Goto Soon, the senior developer and his friends Sheepish and Zub. Waterfall is the story of their struggles against the forces out to ensure they never complete a software project again: their boss Machiovelle O’Puss, Stu Bunn (the project manager pig), The Marketing Peacock, Kevin The Surprisingly Senior Inefficiency Beetle, and a cast of other lunatics!
Based on true events.
Transcript:
The Developers and Managers are in a meeting. The Marketing Peacock is chairing.
Peacock: Welcome to my, that is me, my own meeting! You remember that plan I, myself, had a short while ago? The Best Plan Ever, some called it? Well, my Best Plan Ever (that I thought of, myself) is now scheduled to go live next month! I'm such a genius!
Machiavelli O'Puss, Dept. Head: Yes, I've already chosen a much larger office and settled on a more impressive title (pending this go live). It also comes with a larger salary, I've decided.
Stuart Bunn, Project Pig: Well, I don't know- is this the plan to do A Thing?
Peacock: It sends thrills down my spine just thinking about how great a plan it is! Yes, my plan for A Thing is truly the best plan ever.
Stuart: Are you sure it's what we should be doing, though? I'm not technical, but...
The Product Owner: Growl mumble burble burble new feature!
Stuart: Well, fair enough!
Zub, Developer: So... what is this thing we're building?
[The managers all look horrified and shocked]
Machiovelle: I didn't want to let You People into this meeting, so pack it in and behave!
Zub: B-but we can't build it if we don't know what it is!
Peacock: Fret not! Trust me, my plan is truly a brilliant stroke of amazingness!
Machiovelle: Yes, I've heard quite enough of this cynicism!
Goto, another Developer: Are you all actually mad?! You want something to go live and haven't even told us what we're building!
Machiovelle: ...Goto, I think you should leave. Go to HR and tell them I've sent you there because of your, frankly, sickening attitude.
[Colin, the Security Creature, swoops in and drags away Goto]
Stuart: Sorry mate, she's right.
Zub: But what are we building?!
Sheepish, a third Developer: I don't care... I just don't want Scary Octoboss to yell at me...
Machiovelle: I have a lot riding on this: you screw it up and I'll screw you up!
Peacock: Oh my brilliance will carry my plan through, fear not! Perhaps you should just scuttle off and start doing that 'code' silliness you do? I'm too brilliant to bother myself with it. Simply check back next week and I'll tell you if you're building the right thing!
[All leave except for Zub and Sheepish]
Zub: I wonder if it's too late to join Goto in HR...
Sheepish: Hurray! She didn't yell at me!
0 notes
Photo

Waterfall Short #2: Field Guide to Your Colleagues- Kevin the Surprisingly Senior Inefficiency Beetle
Kevin is a True Rock Star of software. He's got the lot- the swagger, the patter and enough religious views about How It Should Be Done to fill a cathedral. Unfortunately he just doesn't write any code: he's too busy pondering whether It Is (or Is Not) and what Uncle Bob or Jimmy Bogard would do. His bosses love him at the start of the project, because he has some huge ideas about how to do it. When it's still not done 6 months later, their enthusiasm for him is shipping water badly. To his colleagues, he's a Holier-Than-Thou One-Upper who earns enough to buy a small country.
Amalgamated Biscuits and Fluff Inc. (a division of GloboDynamix Weapons Systems) is the setting for our heroes: Goto Soon, the senior developer and his friends Sheepish and Zub. Waterfall is the story of their struggles against the forces out to ensure they never complete a software project again: their boss Machiovelle O’Puss, Stu Bunn (the project manager pig), The Marketing Peacock, Kevin The Surprisingly Senior Inefficiency Beetle, and a cast of other lunatics!
Based on true events.
0 notes
Photo

Waterfall #3: I knew agile didn’t work!
Amalgamated Biscuits and Fluff Inc. (a division of GloboDynamix Weapons Systems) is the setting for our heroes: Goto Soon, the senior developer and his friends Sheepish and Zub. Waterfall is the story of their struggles against the forces out to ensure they never complete a software project again: their boss Machiovelle O’Puss, Stu Bunn (the project manager pig), The Marketing Peacock, Kevin The Surprisingly Senior Inefficiency Beetle, and a cast of other lunatics!
Based on true events.
Transcript:
Waterfall, by Kaylee and Cloud. Issue 3.
In the office Goto Soon, Zub and Sheepish are putting the finishing touches to the newest project.
Goto: And so, gentlemen; ladies; etc., with this commit our new customer portal is done!
Zub: Good work, all round!
Sheepish: It's beautiful! Sniff!
Zub: And no thanks to The Marketing Peacock for fixing the go-live date in stone before any code was written!
Sheepish: Or the BAs for missing a load of functionality!
Goto: Or the devs for gold-plating architecture and chasing the latest framewo-
Zub and Sheepish: Shut up!
Goto: It didn't help that every time the product owner changed their mind about something fundamental, we were told to 'just be agile'... even though the boss insists on waterfall!
Zub: Well never mind! We've implemented the last of the user testing feedback and we're ready to go!
Later, at the demo, three of the Big Wheels of the company have finished looking at the finished article: Machiovelle O'Puss (Department Head), Stuart Bunn (Project Pig) and The Product Owner.
All three: Hmm... no, this can't go live.
Machiovelle: For me, what the customer portal really needs is a bigger office. And a new company car- my Audi is dirty.
Stuart: I know 'the users' like it, but what do they know? What if they're wrong? Or not? Hmm...
The Product Owner: Burble growl new feature growl mumble mumble burble new paradigm...
Outside the demo Zub, Sheepish and Goto are listening in. Being nearer, Zub and Goto have heard enough to know what's happening. Goto is amending his resume and Zub is sobbing against the wall.
Sheepish: I have a good felling about this!
Stuart (From inside the demo): ...I knew 'agile' didn't work...
0 notes
Photo

Waterfall Short #1: Why is the project late?
Amalgamated Biscuits and Fluff Inc. (a division of GloboDynamix Weapons Systems) is the setting for our heroes: Goto Soon, the senior developer and his friends Sheepish and Zub. Waterfall is the story of their struggles against the forces out to ensure they never complete a software project again: their boss Machiovelle O’Puss, Stu Bunn (the project manager pig), The Marketing Peacock, Kevin The Surprisingly Senior Inefficiency Beetle, and a cast of other lunatics!
Based on true events.
Transcript:
Goto, Sheepish, The Product Owner and Zubb are all sat around a large meeting table. Zub looks mournful, Sheepish is shivering and Goto looks dazed. The Product Owner is thinking about a helicopter. Machiovelle O'Puss (AKA Scary Octoboss) is chairing the meeting.
Machiovelle: This is our seventh emergency meeting this week! Why is the project still late?
Stuart Bunn (Project Pig, entering along with The Marketing Peacock): Excuse us, we had this room booked for a new feature planning meeting?
0 notes
Photo

Waterfall #2: The 5 Stages of Working with JavaScript
Amalgamated Biscuits and Fluff Inc. (a division of GloboDynamix Weapons Systems) is the setting for our heroes: Goto Soon, the senior developer and his friends Sheepish and Zub. Waterfall is the story of their struggles against the forces out to ensure they never complete a software project again: their boss Machiovelle O’Puss, Stu Bunn (the project manager pig), The Marketing Peacock, Kevin The Surprisingly Senior Inefficiency Beetle, and a cast of other lunatics!
Based on true events.
Transcript: Waterfall, Issue 2. By Kaylee and Cloud.
Title: "The 5 stages of working with JavaScript"
Subheading: "Denial"
Zzub: [Pointing to a slideshow] "We’re writing everything in Sandwich.js now!"
Sheepish: [Looking depressed] "Is that another JavaScript framework!?"
Zzub: "It’s not just a framework, it’s a whole architecture! You wrap the DOM in two copies of itself, and you have to peel off a copy every time you make a change and then restore it once all the tests pass. That way, you never pollute your scope and you’ve got a constant changelog within the app itself. And it does compile to JavaScript but you have a choice of syntax libraries; Peanut Butter, Marmite … that one only uses vowels… Banana… that one uses crescent shaped functions with precisely one if statement that must be < 50% width of the declaration and return statement…"
Sheepish: "Oh, you’ve got to be joking. That’ll never take off."
Subheading: "Anger"
Sheepish: "But I just learned a new JavaScript framework! This is totally unfair! I’m an adult and I don’t have time to constantly study new technologies and they CAN’T MAKE ME DO IT!"
Barrista: "Sir, we’ve been here for some time. Can you please complete this sentence: “The type of coffee I would like to buy is…”"
Subheading: "Bargaining"
Sheepish: [Scheming] "Maybe if I improve my CSS skills, nobody will mind that I didn’t learn the new framework… and I’ll buy coffees for everyone in the office! It’s brilliant, brilliant!"
Subheading: "Depression"
Sheepish: [Staring sadly at the grave of their career] "Well, I had a good run as a software developer. Time to admit I’m a fraud, resign in disgrace, and start synthesizing my own coffee-like beverage out of apple juice and Snickers bars."
Goto Soon: [Helpfully] "I’m pretty good with Sandwich.js… I could teach you, if you want?"
Subheading: "Acceptance"
Sheepish: "This is great, I totally see how it improves on the framework now! Thanks for the help, chum!"
Goto: "You’re welcome. By the way, we’ve got a new ticketing system that makes it much easier to log requests and…"
Sheepish: [Angrily] "It’ll never take off!"
Goto: "But it’s already…"
Sheepish: [Peevishly] "You can’t make me! Here, you can have my coffee. This is the worst thing that’s ever happened to anyone!"
Goto: "Just drag the ticket into this column and it marks it as done."
Sheepish: "Cool!"
0 notes
Photo

Waterfall #1
Amalgamated Biscuits and Fluff Inc. (a division of GloboDynamix Weapons Systems) is the setting for our heroes: Goto Soon, the senior developer and his friends Sheepish and Zub. Waterfall is the story of their struggles against the forces out to ensure they never complete a software project again: their boss Machiovelle O’Puss, Stu Bunn (the project manager pig), The Marketing Peacock, Kevin The Surprisingly Senior Inefficiency Beetle, and a cast of other lunatics!
Based on true events.
Transcript:
The Marketing Peacock: Thank you for joining me, The Marketing Peacock, to discuss my (myself's) great idea! I believe we should produce A Thing. The CEO said I am a genius! Yes, I (that is, me) definitely believe in this Thing that we should... nay, must produce!
Stuart Bunn, Project Pig: Well, I dunno... At the end of the day, A Thing may be what we want now, but what if it isn't tomorrow? I'm not technical, but...
Machiavelli O'Puss, Dept. Head: Yes, indeed, Stu. For me, I want to see more paperwork, at least two more meetings and an en-suite added to my office before we agree more blue-sky actionables for delivering value here.
Outside, Goto and Sheepish are lurking in the corridor. There are large, threatening signs on the meeting room door that read "Big Meeting. This Means You Minions!" Various certificates and awards line the wall, including 'Most Meetings', 'Work 1st, Then Death' and a list of Values: 1. Up, Not Down; 2. Soap; 3. Yes, not if.
Goto: They've been in there for three days! Shouldn't we tell them that the office is on fire again!
Sheepish: But Scary Octoboss said that if I talk to her again, without becoming a director first, she'd cut my pay...
0 notes