Error driven development

So… it is a beautiful Wednesday and an idea popped into my head. Error-driven development😲😲😲!!! Did a...

Cover image for Error-driven Development?

femolacaster

So… it is a beautiful Wednesday and an idea popped into my head. Error-driven development😲😲😲!!! Did a quick google search on it and realized it wasn’t just me that has gotten the revelation at some point😒.

The unwritten consensus is that error-driven development is a pun on TDD and somewhat a methodology that enforces you to write errors and exceptions when things go or could go wrong as well as writing tests. Other ideas about the term range from the iteration of errors being a key force into the etymology of agile and how fixing and studying these errors over time could make you a better developer.

That was informative for me but I was however inspired in an unfamiliar direction.

And here are my thoughts:

Yes. Error-driven development should be a software development methodology. Which takes some ideas from other software methodologies such as agile, TDD, etc.

So, my thoughts are, it should not be an alternative to TDD. Rather, it is a variation. Here are some principles I came up with:

  • Error-driven development is based on the principle that to disrupt is to forget. So on the successful pass of a test case, it forgets that the test case has been passed by invalidating it with the next most interesting insight.

  • Error-driven development would eventually disrupt the original requirements rather than build or extend the requirement.

  • Hence, there is a requirement in the beginning but the requirements are forgotten as iteration increases.

  • Unlike the Agile methodology, error-driven development does not iterate or consider changes based on business value. Instead, it iterates based on the quality of insight. The most insightful knowledge gained from the last-passed test case is the point for invalidation.

  • Error-driven development is then best suited for non-commercial products. And experimental or research-based project and programs of a long-span whose primary aim is to gain insights(It is amazing that software development which is science is largely concerned with commercial value and have less interest in experiments and hypotheses testing anyway).

So, let’s discuss. Is error-driven development worth a try based on these principles?

Error Driven Development
in JavaScript

Error Driven Development is a pun on Test Driven Development. So besides writing tests, you should more importantly, write errors!
And by errors I mean that the program should «throw» an error when something is wrong.

You might think that writing code that intentionally makes a program «crash» makes it unreliable, but it’s quite the contrariety.
To make a bug free program, it should crash at any opportunity, on all kind of errors …

It should not only crash, it should scream loud at your face (the developer):

  • What the error is
  • in what source file and line number
  • Give a call stack
  • and state data.

And if it’s running in production, the error should be logged, and a developer notified. And the program/daemon instantly restarted.

Code examples

Take this simple function as an example:

function sum(x, y) {
	return x + y;
}

What will happen if it’s called with only the first argument? Or with an array as second argument?

sum(1, 2)     => 3
sum(1)        => NaN
sum(1, [1,2]) => '11,2'
sum(1, "1")   => '11'

In JavaScript we get a lot «for free». Throwing an error in JavaScript (nodejs) crashes the program and prints out a call stack.
We can then provide the rest of the information in the Error message.

function sum(x, y) {
	if(!isNumeric(x) throw new Error("Expected first argument x=" + x + " to be a numeric value!");
	if(!isNumeric(y) throw new Error("Expected second argument y=" + y + " to be a numeric value!");
	
	return x + y;
	
	function isNumeric(n) {
		return !isNaN(parseFloat(n)) && isFinite(n);
	}
}

function addPerson(name, age) {
	if(name.length < 1) throw new Error("name=" + name + " is only " + name.length + " characters long!");
	if(age < 0 || age > 150) throw new Error("age=" + age + " is below zero or above 150!");  
	//... Some code here
}

function disable(settings, option) {
	if(!settings.hasOwnProperty(option) throw new Error("option=" + option + " does not exist in settings=" + JSON.stringify(Object.keys(settings)) );
	//... Some code here
	if(settings[option] != false) throw new Error("settings[" + option + "]=" + settings[option] + ", expected it to be false!");
}

Sometimes we do not want to crash though, but then we can use try-catch!

// Important that all these functions run
var gotError = false;
for(var=0; i<funs.length; i++) {
	try {
		funs[i](); // Execute the function
	}
	catch(err) {
		console.warn("Error: " + err.message + "n" + err.stack);
		gotError = true;
	}
}
if(gotError) throw new Error("Got error when running functions! See console log");

Are you insane?

You can take the error checking to another level by checking for stuff that should never happen.
A few extra if’s here and there will not slow down your program, unless you do it in a tight loop. But it can keep you sane.
And one nanosecond of extra compute time is better then spending several hours debugging an error that should never happen.
And weird stuff does happen! For example «bit flips» or «data rot», like a bad hard drive, RAM, or a bit error over the wire, that passes the CRC.

Still don’t believe me? Error checks is common in life depending software, like avionics. It’s usually much better to quickly reboot a micro-service,
then to have a bad state, like having the altimeter show the wrong value, or spreading the bad state all over the system.

Human errors

Must bugs are caused by those who write the software. By having your functions constantly check the inputs (arguments) for errors,
and show friendly error messages, most bugs will be found quickly during manual testing.
This is especially important in JavaScript, where most data types can be mixed together without any errors or warnings by the compiler.
But before you rant on JavaScript for being «weakly typed», guess whats true about all bugs ever made in a strongly typed language? They all passed the type checker!

Writing errors VS «unit» testing

function magicNumber(n) {
	
	if(n < 1 || n > 10) throw new Error("n needs to be between 1 to 10");
	
	n = n * 3;
	n = n + 6;
	n = n * 3;
	
	var str = n + "";
	
	n = 0;
	
	for(var i=0; i<str.length; i++) {
		n = n + parseInt(str[i]);
	}
	
	return n;
}

Unit test

assert(magicNumber(1) == 9, "magicNumber should always return number 9");
assert(magicNumber(2) == 9, "magicNumber should always return number 9");
assert(magicNumber(3) == 9, "magicNumber should always return number 9");
assert(magicNumber(4) == 9, "magicNumber should always return number 9");
assert(magicNumber(5) == 9, "magicNumber should always return number 9");
assert(magicNumber(6) == 9, "magicNumber should always return number 9");
assert(magicNumber(7) == 9, "magicNumber should always return number 9");
assert(magicNumber(8) == 9, "magicNumber should always return number 9");
assert(magicNumber(9) == 9, "magicNumber should always return number 9");
assert(magicNumber(10) == 9, "magicNumber should always return number 9");

Error test

if(n != 9) throw new Error("Expected n to be 9");

The advantage of error checks over «unit testing» is that you simply can’t have your «unit tests» cover every single state. While the error checks test real world data.

There are cases when error checks wont be enough though. For example if you have a function that does many things, like a food machine:

function foodMachine(ingredients) {
	return plate;
}

Every time you implement a new dish to that function, or you find a bug, make sure you also write a test that covers it! Or you will end up with so called regression bugs,
which means your changes caused another bug, or you cause a (dejva-vu) bug that you have already fixed before.

Unit test

assert(foodMachine([
	"pasta", 
	"bacon", 
	"parmesan", 
	"egg", 
	"cream"
]) == "Carbonara", "Expected Carbonara");

You should however avoid such functions. Having your programs, modules and functions only do one thing will be much easier with less bugs, and easier to test, both manually, automatic and with error checks.

But whatever you do, do not make your tools restrict how you design your code.
A common mistake with Test Driven Development is dividing the code up too much, into smaller parts,
which makes it easier to test, but you’ll lose context of what the code does.
This probably deserves it’s own blog post/rant, but I’ve seen a lot of code bases lately,
that is so fragmented that it’s impossible to see the code flow, and where those tiny parts fits into the whole. And while there’s code reuse inside the program itself,
their «modules» are useless without the rest of the program.


Written by Mars 22, 2016, updated 23 June 2016.

16 Apr 2009

If you’re waiting around for users to tell you about problems with your website or application, you’re only seeing a tiny fraction of all the problems that are actually occurring. The proverbial tip of the iceberg.

iceberg.jpg

Also, if this is the case, I’m sorry to be the one to have to tell you this, but you kind of suck at your job — which is to know more about your application’s health than your users do. When a user informs me about a bona fide error they’ve experienced with my software, I am deeply embarrassed. And more than a little ashamed. I have failed to see and address the issue before they got around to telling me. I have neglected to crash responsibly.

The first thing any responsibly run software project should build is an exception and error reporting facility. Ned Batchelder likens this to putting an oxygen mask on yourself before you put one on your child:

When a problem occurs in your application, always check first that the error was handled appropriately. If it wasn’t, always fix the handling code first. There are a few reasons for insisting on this order of work:

  1. With the original error in place, you have a perfect test case for the bug in your error handling code. Once you fix the original problem, how will you test the error handling? Remember, one of the reasons there was a bug there in the first place is that it is hard to test it.
  2. Once the original problem is fixed, the urgency for fixing the error handling code is gone. You can say you’ll get to it, but what’s the rush? You’ll be like the guy with the leaky roof. When it’s raining, he can’t fix it because it’s raining out, and when it isn’t raining, there’s no leak!

You need to have a central place that all your errors are aggregated, a place that all the developers on your team know intimately and visit every day. On Stack Overflow, we use a custom fork of ELMAH.

stackoverflow exception log

We monitor these exception logs daily; sometimes hourly. Our exception logs are a de-facto to do list for our team. And for good reason. Microsoft has collected similar sorts of failure logs for years, both for themselves and other software vendors, under the banner of their Windows Error Reporting service. The resulting data is compelling:

When an end user experiences a crash, they are shown a dialog box which asks them if they want to send an error report. If they choose to send the report, WER collects information on both the application and the module involved in the crash, and sends it over a secure server to Microsoft.

The mapped vendor of a bucket can then access the data for their products, analyze it to locate the source of the problem, and provide solutions both through the end user error dialog boxes and by providing updated files on Windows Update.

Broad-based trend analysis of error reporting data shows that 80% of customer issues can be solved by fixing 20% of the top-reported bugs. Even addressing 1% of the top bugs would address 50% of the customer issues. The same analysis results are generally true on a company-by-company basis too.

Although I remain a fan of test driven development, the speculative nature of the time investment is one problem I’ve always had with it. If you fix a bug that no actual user will ever encounter, what have you actually fixed? While there are many other valid reasons to practice TDD, as a pure bug fixing mechanism it’s always seemed far too much like premature optimization for my tastes. I’d much rather spend my time fixing bugs that are problems in practice rather than theory.

You can certainly do both. But given a limited pool of developer time, I’d prefer to allocate it toward fixing problems real users are having with my software based on cold, hard data. That’s what I call Exception-Driven Development. Ship your software, get as many users in front of it as possible, and intently study the error logs they generate. Use those exception logs to hone in on and focus on the problem areas of your code. Rearchitect and refactor your code so the top 3 errors can’t happen any more. Iterate rapidly, deploy, and repeat the proces. This data-driven feedback loop is so powerful you’ll have (at least from the users’ perspective) a rock stable app in a handful of iterations.

Exception logs are possibly the most powerful form of feedback your customers can give you. It’s feedback based on shipping software that you don’t have to ask or cajole users to give you. Nor do you have to interpret your users’ weird, semi-coherent ramblings about what the problems are. The actual problems, with stack traces and dumps, are collected for you, automatically and silently. Exception logs are the ultimate in customer feedback.

carnage4life: getting real feedback from customers by shipping is more valuable than any amount of talking to or about them beforehand

Am I advocating shipping buggy code? Incomplete code? Bad code? Of course not. I’m saying that the sooner you can get your code out of your editor and in front of real users, the more data you’ll have to improve your software. Exception logs are a big part of that; so is usage data. And you should talk to your users, too. If you can bear to.

Your software will ship with bugs anyway. Everyone’s software does. Real software crashes. Real software loses data. Real software is hard to learn, and hard to use. The question isn’t how many bugs you will ship with, but how fast can you fix those bugs? If your team has been practicing exception-driven development all along, the answer is — why, we can improve our software in no time at all! Just watch us make it better!

And that is sweet, sweet music to every user’s ears.

layout

post

  • The Setup
  • Test first
  • Github Authentication
  • Logging Out

## [The Setup](#the_setup)

Prerequisites:

Ok, first step, we’ll make a new Rails project:

rails new github_auth --skip-bundle -T
cd github_auth
rm public/index.html
rm app/assets/images/rails.png
rm README.rdoc
touch Readme.md
echo "Basic readme to be filled in later" > Readme.md

Once all that is done, open up Gemfile and make it look like this:

{% highlight ruby %}
source ‘https://rubygems.org’

gem ‘rails’, ‘3.2.7’
gem ‘jquery-rails’
gem ‘omniauth-github’

group :development, :test do
gem ‘sqlite3’
gem ‘rspec-rails’
gem ‘capybara’
end

group :production do
gem ‘pg’
end

group :assets do
gem ‘sass-rails’, ‘> 3.2.3’
gem ‘coffee-rails’, ‘> 3.2.1’
gem ‘uglifier’, ‘>= 1.0.3’
end
{% endhighlight %}

Now run

and

rails generate rspec:install

and finally:

git init
git add .
git commit -m "I'M PAR TY ING"

## [The Failing Test](#failing)

Ok, let’s do this right. Let’s write a failing test to guide our development.

mkdir spec/requests
touch spec/requests/github_auth_spec.rb

In spec/requests/github_auth_spec.rb:
{% highlight ruby %}
require ‘spec_helper’

describe «logging in with github» do
it «should be successful» do
visit root_path
click_link ‘Login with Github’
expect(page).to have_content ‘Logged in Successfully’
end
end
{% endhighlight %}

Run the test:

and you should see that it fails. Now all that remains is to get this test passing…

The first failure is:

undefined local variable or method `root_path'

which we fix by adding a root_path in config/routes.rb, like so:

{% highlight ruby %}
GithubAuth::Application.routes.draw do
root to: ‘static_pages#index’
end
{% endhighlight %}

Now our test should give a new error:

ActionController::RoutingError:
       uninitialized constant StaticPagesController

which we fix by creating the file app/controllers/static_pages_controller.rb and putting this in it:

{% highlight ruby %}
class StaticPagesController < ApplicationController

end
{% endhighlight %}

which gets us past our current failure. Our new error is:

The action 'index' could not be found for StaticPagesController

Let’s fix that shall we? Update app/controllers/static_pages_controller.rb so it looks like this:

{% highlight ruby %}
class StaticPagesController < ApplicationController
def index

end
end
{% endhighlight %}

See that we get a new error:

Missing template static_pages/index

To fix this, we need to create the template it is looking for. Create the folder app/views/static_pages and add the file app/views/static_pages/index.html.erb to your project.

Finally! Our first interesting error:

Capybara::ElementNotFound:
       no link with title, id or text 'Login with Github' found

Let’s get rid of it. How? Well, it’s looking for a link called ‘Login with Github’, so let’s make one. In app/views/static_pages/index.html.erb add this line:

{% highlight ruby %}
<%= link_to ‘Login with Github’ %>
{% endhighlight %}

Now at this point, if you re-run the tests, the last failure is:

Failure/Error: expect(page).to have_content 'Logged in Successfully'
       expected there to be content "Logged in Successfully" in "GithubAuthnnLogin with Githubnnn"

We could cheat here, and just add the content Logged in Successfully to the page and be done with this spec, but that doesn’t actually get us logged in with Github. So let’s login with Github.

The Authentication With Github

Authentication using the omniauth-github gem we included in our Gemfile is actually pretty easy, even if the steps on how to do it are all spread around the web. Here, I provide a walkthrough to save you some Googling, and as a reference for myself when I inevitably forget what the hell I did yesterday.

Change app/views/static_pages/index.html.erb to look like this:

{% highlight ruby %}
<%= link_to ‘Login with Github’, github_auth_path %>
{% endhighlight %}

You will get this error:

ActionView::Template::Error:
       undefined local variable or method `github_auth_path'

Open up config/routes.rb and add:
{% highlight ruby %}
get ‘/auth/github’, as: :github_auth
{% endhighlight %}

and you should get a new error:

ActionController::RoutingError:
       uninitialized constant AuthController

We fix this by creating config/initializers/omniauth.rb and adding the following to it:
{% highlight ruby %}
Rails.application.config.middleware.use OmniAuth::Builder do
provider :github, ENV[‘GITHUB_KEY’], ENV[‘GITHUB_SECRET’]
end
{% endhighlight %}

Run your tests again, and you should get a new error:

ActionController::RoutingError:
       No route matches [GET] "/login/oauth/authorize"

Whoops! Guess we forgot to turn on test mode for omni-auth. Let’s do that now. Add the following line to config/environments/development.rb and config/environments/test.rb:
{% highlight ruby %}
OmniAuth.config.test_mode = true
{% endhighlight %}

Now we should see a new error:

ActionController::RoutingError:
       No route matches [GET] "/auth/github/callback"

Ok, fine. Be that way. But not for long! Turns out we just forgot to add the other piece needed for Omniauth to work: the callback url it should go to after the external authorization is finished. Duh! How could we be so forgetful?

Anyways, let’s fix our error. Add this line to your routes file:

{% highlight ruby %}
match ‘/auth/github/callback’ => ‘sessions#create’
{% endhighlight %}

Hooray! We have a callback url now. But wait a minute. What’s that? A new error you say?

ActionController::RoutingError:
       uninitialized constant SessionsController

Whoops! We know how to fix this kind of error now. Add the file app/controllers/sessions_controller.rb to your project, and the following code in the new file:

{% highlight ruby %}
class SessionsController < ApplicationController; end
{% endhighlight %}

Great! Now we have a new error:

AbstractController::ActionNotFound:
       The action 'create' could not be found for SessionsController

We’ve fixed one like this before, so try and do it yourself before looking below.

Edit app/controllers/sessions_controller.rb to look like this:

{% highlight ruby %}
class SessionsController < ApplicationController
def create

end
end
{% endhighlight %}

Getting closer…but now we have a new problem. Create doesn’t have a template to render:

ActionView::MissingTemplate:
       Missing template sessions/create

Lucky for us we don’t actually want create to render a template, so we just need to override the Rails default and set up create so that it redirects. Before we do that though, let’s give our session something to play with, in this case, the response from authorizing with github. Add the following to app/controllers/sessions_controller.rb:

{% highlight ruby %}
class SessionsController < ApplicationController
def create
session[:github] = request.env[‘omniauth.auth’]
redirect_to root_path
end
end
{% endhighlight %}

So close now! A new error approaches:

Failure/Error: expect(page).to have_content 'Logged in Successfully'
       expected there to be content "Logged in Successfully" in "GithubAuthnnLogin with Githubnnn"

Our test is finally through the click_link line, and has continued on to the actual expectation, which failed as expected. Let’s make it pass. Edit app/controllers/sessions_controller.rb to look like this:

{% highlight ruby %}
class SessionsController < ApplicationController
def create
session[:github] = request.env[‘omniauth.auth’]
flash[:notice] = ‘Logged in Successfully’
redirect_to root_path
end
end
{% endhighlight %}

Now our tests will still fail at this point, because we aren’t actually rendering the flash in our view. To render the flash in the view, change app/views/static_pages/index.html.erb to look like this:

{% highlight erb %}
<%= flash[:notice] if flash[:notice] %>
<%= link_to ‘Login with Github’, github_auth_path %>
{% endhighlight %}

BOOM! Our test passes!

Unfortunately, we can’t logout. This seems like a bit of an oversight on our part. Let’s fix that, shall we?

The Log Out

Test first, as always. Open up spec/requests/github_auth_spec.rb and add the following test:

{% highlight ruby %}
describe «logging out» do
it «should be successful» do
visit root_path
click_link ‘Login with Github’
click_link ‘Logout’
expect(page).to have_content ‘Logged out Successfully’
end
end
{% endhighlight %}

Running the tests we see that Rspec is not very happy:

Capybara::ElementNotFound:
       no link with title, id or text 'Logout' found

How do we appease the Rspec? Well, it would make sense to have a ‘Logout’ link when we are logged in, wouldn’t it? Let’s add one. Add the following to app/views/static_pages/index.html.erb:

{% highlight ruby %}
<%= link_to ‘Logout’ %>
{% endhighlight %}

We get the following error:

Failure/Error: expect(page).to have_content 'Logged out Successfully'
       expected there to be content "Logged out Successfully" in "GithubAuthnnLogin with GithubnLogoutnnn"

We can fix this trivially, but let’s have a little more fun. Edit the line we just added to app/views/static_pages/index.html.erb to this:

{% highlight ruby %}
<%= link_to ‘Logout’, logout_path %>
{% endhighlight %}

Uh oh! We regressed, and now our first test is failing with:

ActionView::Template::Error:
       undefined local variable or method `logout_path'

Edit config/routes.rb to have this code:

{% highlight ruby %}
get ‘/logout’ => ‘sessions#destroy’, as: :logout
{% endhighlight %}

We know how to fix this error:

AbstractController::ActionNotFound:
       The action 'destroy' could not be found for SessionsController

Open up app/controllers/sessions_controller.rb and define the destroy method:

{% highlight ruby %}
def destroy
reset_session
end
{% endhighlight %}

Which leads us to:

ActionView::MissingTemplate:
       Missing template sessions/destroy

We don’t actually care about rendering a template, so let’s just redirect. And while we’re at it we will reset the session and flash a message as well:

{% highlight ruby %}
def destroy
reset_session
flash[:notice] = «Logged out Successfully»
redirect_to root_path
end
{% endhighlight %}

And with that, we’re back to green!

Now it doesn’t make much sense to show a login AND logout link at the same time, but I will leave that as an exercise to the reader.

P.S. This isn’t really TDD, it’s more EDD, or Error Driven Development, with just enough of a smoke test to keep me honest. I use the errors as a check list to keep me on task, since I tend to have trouble focusing for long stretches of time. Feedback welcome!

P.P.S. I left out the ENV variable assignment for the github key and secret. Pshh, you only need those if you plan to deploy your app to a production environment, and who wants to do that???

Update: setting your ENV variables

P.P.P.S If you want to see what the github session info looks like, add this to app/views/static_pages/index.html.erb:

{% highlight ruby %}

<%= session[:github].as_json if session[:github] %>

{% endhighlight %}

Enjoy!

top

I’m pretty new to Rust, and am finding that my logic (mostly) works however, I seem to really struggle with the Rust concepts and low-level programming concepts (types, memory, borrowing, generics, traits, lifetimes) this leads to what I see as compiler error driven development where I run the code, check the errors, fix (or try to fix) the errors before succeeding and carrying on or finding new errors and the process repeats. I call it this because it reminds of TDD except whereas TDD is designed to check logic, CEDD is checking that I’m conforming to the Rust way of doing things.

To be clear, I don’t think this is a good thing, but I just want to check if this is a ‘normal’ phase to go through at the beginning — particularly since I come from a background of high-level, weakly typed, dynamic languages only.

If this is a rite of passage, I’ll be less concerned, but I know that this is a symptom of not truly grasping the concepts well enough. I’m just not sure if I will learn the concepts by continuing to go through with this CEDD phase, or if I need to try a different tack (and if so, what?).

For clarity, I’m currently reading The Book and I am facing these issues as I try the exercises and in particular extending the exercises with my own functionality.

This article was contributed by Natasha Postolovski, a Graduate Software Developer at ThoughtWorks. You can follow her on Twitter: @npostolovski

More people than ever before are entering software development from non-traditional backgrounds. The number of coding bootcamps is increasing, and there’s a broad push from the industry to attract more diverse types of developers. Many companies are no longer solely focused on hiring senior developers, and have realized that it may be smarter to train-up the next generation of senior developers instead.

Software development pays well, the industry is booming, and compared to many other careers, software developers get treated very well. But I think the thing that draws most career-changers to software development is the search for more rewarding work.

If you’re reading this, you’re most likely considering a change from another career. I was in your position less than a year ago, and I know that it’s a scary, but exciting, place to be.

There’s one question you should ask yourself above all others: if you make the switch to software development, will you like it? Because getting to a level of skill where you are hireable will be a lot of work, and you may be leaving behind a promising career in the process. The stakes are high.

If you don’t know whether you’re going to like it, build things with code. Create a Tic Tac Toe game. Start a small online business and do the development yourself. Contribute to open source. Make games. Complete programming challenges. Build a personal website and do all the design and development yourself. If you enjoy any of these things, there’s a good chance you’ll enjoy working as a software developer.

Switching careers can be an epic, challenging journey – but I hope that it will be one of the best things you’ve ever done.

There are a thousand ways to learn to program, and the route you take will depend on how you learn best. You can take online courses, find a teacher or mentor, watch YouTube videos, read books, do a Computer Science degree, watch screencasts, or simply jump onto the command line and start experimenting, hitting up Stack Overflow as you go. Isis Anchalee of #ILookLikeAnEngineer fame recently put together a great summary of ways to learn to code.

I did a combination of all the above things when I was learning to code, but there were a few things that helped me more than any others:

Have something you (passionately) want to make

Whether it’s a blog, a game, a website, a SaaS startup, an online dating website, or an app to manage your family’s finances, having a project you’re motivated to build will push you through the tough times when learning how to program. A real-world use-case for your skills will accelerate your learning.

I spent a few months working as a TA at a coding bootcamp. The students who progressed fastest with their skills were those who had something they desperately wanted to build, because everything they learned, they could apply in their project.

Do a coding bootcamp, if you can, and if you feel it will work for you

When I was first learning to code there weren’t any coding bootcamps where I live in Melbourne, Australia. I took the rather drastic step of moving to Chicago for 3 months to be part of The Starter League. It was the defining choice in my journey to become a software developer.

A good coding bootcamp will give you a focused environment, help when you need it, and support when the journey gets tough. When you’re first learning to code it can be really hard to know what you should focus on. Through experience, coding bootcamps are very good at scoping this down to the essentials you need to build or design web apps.

A good coding bootcamp will also assume no prior programming knowledge, and teach you the skills you need from the ground up, unlike many programming articles and videos, which will be written with professional programmers in mind.

Coding bootcamps can be expensive, and they’re not for everyone, but if you feel like it might be worth the investment, I highly recommend them.

Connect with other people learning to program

Learning to code can be difficult at times. Having a network of other people going through the same challenges can be hugely important. If you don’t know anyone making the transition, attend local meetups and talk to people there, especially if you’re focused on languages popular among Junior developers (Ruby and JavaScript in particular). If you’re lucky, your local programming meetup may even host a ‘Newbies’ night now and again. Make sure to go!

Find a mentor who works in the industry

A friendship or mentorship with a working software developer can also be immensely helpful in your journey. They will know what the interview culture is in your local industry, will be able to give you advice when you get stuck, help you focus on the most important skills to learn, and give feedback on your code. If you’re lucky enough to find a software developer generous with their time in this way, make sure to give back somehow, even if it’s just buying lunch when you meet. Once again, meetups are a great way to meet potential mentors. If meetups aren’t for you, or there are none in your local area, you can also find mentors on CodeMentor.

Focus your learning

If you’re hoping to do backend programming primarily (the engine of most apps, not the visual presentation), focus on learning one language and one web framework as well as you can. Also aim to be somewhat familiar with JavaScript, HTML and CSS, as many roles will have you working with both the frontend and backend of an application. If you’re aiming for a front-end role, focus on JavaScript, HTML and CSS. You might also focus on a popular JavaScript MVC framework like React or AngularJS.

Be prepared to invest in your career change

You can spend a lot on the transition, Books, courses, classes, and screencast subscriptions can add up to hundreds of dollars a month, and many boot camps are over $10,000. Despite the hype around programmer salaries, you can expect to make between $40k and $60k as a Junior developer, with higher starting salaries possible in startup hubs like San Francisco and New York. At first, it might seem like you’ve invested a lot in this career change without much financial reward. Over the long term, though, this investment should pay off, with developer salaries steadily rising into six figure territory as you gain experience.

Don’t worry if your journey isn’t linear

Learning to program is tough, it takes time, and if you’re juggling a pre-existing career and other commitments, it may be difficult to focus on it for more than a few hours a week. You may have doubts, you may get distracted, and you may stop progressing for days, weeks, or months. In my case, there was an almost two year gap between attending a coding bootcamp and getting a job in software development. It could have happened much sooner, but life, and my own doubts, got in the way. Trust that if software development is truly what you want to do, that you’ll find your way eventually, even if you end up taking the scenic route.

When it comes to your GitHub profile, be selective about what you show

GitHub is an online hosting service for git repositories, best described as version-controlled programming projects. When a repository is public on GitHub, anyone can read through your code. Many hiring managers will check the GitHub profile of applicants to get an idea of how they write code when nobody is watching. When evaluating Junior applicants, the hiring managers may not be looking for amazing code, but instead looking for enthusiasm, multiple projects, trying out new things, and a sense of play. Your GitHub profile is a great way to show this, but keep in mind that hiring managers may only have a few spare minutes to review your profile. For this reason, it’s a good idea to only make substantial or interesting projects public. For projects where you were just messing around or going through a tutorial, it may be worth making them private to give your best stuff the limelight.

It’s hard sometimes

Self-doubt is a common trap for Junior developers, especially those from groups who are underrepresented in the software industry. If something feels hard, it’s not because you’re not cut out for this: it’s because you have more to learn, or perhaps, because the thing you’re working on is actually hard. You may also be concerned when something you find challenging seems easy to someone else, especially when that someone else has a similar level of experience. But stick with that person long enough and you’ll likely encounter something they struggle with that you find really easy. We’re all different, we bring different pre-existing skills to the table, and we all practice differently. Programming is like any skill: you can become good at it if you persist long enough and care about getting better. Avi Flombaum, co-founder of the Flatiron School, says “I absolutely believe that anybody can learn how to program in the same way that we know anyone can learn how to read and write.”

Be aware of your blind spots

By all accounts, career-changers have been making waves in the development community. They’re self-starters who sacrificed an existing career, and sometimes a higher salary, in order to become software developers. We’re pretty awesome, but we do have blind spots. The inner-workings of computers and the internet are mind-bendingly complex, especially to anyone from a non-technical background. Mastering one programming language, one web framework, JavaScript, HTML and CSS might take up all your available time. However, when you’re starting out as a Junior developer, you probably won’t realize that these things are just a small slice of the technologies you work with every day. Think about the answers to some of the following questions:

How does your code get run?
How does your language’s interpreter or compiler know when it encounters a syntax error?
How does typing a URL into your browser toolbar result in a web page being rendered on your screen?
How does a web server work?
How do you stay logged into websites even after you close and reopen your browser?
How does your app run on a web server?
Your project is hosted on Heroku or AWS, but what do they use under the hood?
When people say an object is ‘in memory’, what does that mean?
How do you SSH onto a server?
How do you set up and use a build pipeline?
How does your operating system run on your computer?

Of course, this list could be much longer. There’s so much to learn that it can feel overwhelming. The good news is that you don’t need to know the answers to all these questions in order to be hired as a Junior software developer, but you should try to learn them as you go further in your career. You can’t get really good at software development unless you have a working understanding of the tools that you work with every day. Increasing your understanding will empower you to make better choices, become better at debugging, and make better design decisions.

When you’re struggling, take time to appreciate the unique skills you have that Computer Science graduates may not have yet

If you’ve attended or scheduled a work meeting, given tricky feedback at work, been through a performance review, or led a team, you already have valuable skills that recent Computer Science graduates may not have. You may be more at ease talking with stakeholders, better at meetings, planning and organization, simply through having more experience. Most importantly, you may have a better sense of perspective. After all, if you’ve previously worked as a nurse in an operating theatre, you might be more likely to stay cool, calm and collected when a bug pops up in production. After all, nobody is going to get (physically) hurt!

Get experience with pairing

Pairing is the practice of having two developers share one computer and work on the code together. One developer will write code while the other watches and does some of the following things: makes suggestions, asks questions, catches errors, and thinks more broadly about how the code being written fits into the larger program. Because both roles are fatiguing, they will usually swap anywhere from every 15 minutes to ever few hours.

Pairing is a common practice in the industry, and even more common in the coding interview process. You don’t need to be an expert at pairing, but pairing for the first time can be a little intimidating, especially when pairing with a much more senior developer. Despite this, pairing can actually be really fun, and is a fantastic way to learn. If you can, get some practice with pairing before you begin doing coding interviews. If you have a mentor, pair with them. Otherwise, you can find opportunities to pair at hackathons and hack nights in your local area.

Set up a mock programming interview

Programming interviews are likely to be quite different to the interviews you took to get a job in your current career. They often involve coding challenges, writing pseudocode at a whiteboard, pair programming, and feedback on your code. Learn as much as possible about coding interviews by researching them online. Then practice them with a friend. Find a whiteboard and solve simple problems by writing your code on the whiteboard. Get your friend to ask you common programming interview questions. It doesn’t matter if your friend is non-technical. The experience will really help when it comes time to do a real coding interview, as they can be a little intimidating at first!

Before test-driven development, practice error-driven development

Errors will be your constant companion when learning to code. You’ll be breaking stuff all the time, and will be met with lots of error messages. As once non-technical people, error messages can be scary. Before learning to code they may have meant that you wrecked your computer installing a game, or bricked a phone while trying to unlock it. An important mindset when doing programming, however, is to see error messages as trying to help. Though they may fill the screen with red (in the case of Ruby on Rails), or print a confusing and lengthy stack trace to the screen, they are here to help.

When many developers encounter an error message we react a little like we’ve been slapped on the hand, quickly navigating away from our browser or shell window and peering at the code we just wrote, trying to figure out what might have made the computer so angry. In most cases, the computer is already telling us via the error message it just printed, but we  need to slow down and read it before we can reap the benefits.

Jeff Cohen, an instructor at my coding bootcamp, encouraged us to practice error-driven development. This method goes beyond slowing down to read error messages, and instead, you let a succession of errors guide you forward in your development. Call a method that doesn’t exist, see a ‘no method’ error, then write the code to bring that method into existence. Reference a view that doesn’t exist, see a ‘no view’ error, then create the view. Errors are not to be feared, in fact, they can guide you. Just not in production 😉

Learn about and practice test-driven development (at least a little bit)

Once you’re comfortable with error-driven development, test-driven development is the next step in your learning.

Test-driven development is a sought after skill in the industry, and familiarity with it is a requirement to get hired at some software companies. It’s the practice of writing code to ‘test’ how your program behaves, and to drive out a better design for your program. If you’ve ever added some functionality to a program, only to have it break something else that was previously working, this is one of the things test-driven development (often abbreviated as TDD) can help with!

Few programming resources for beginners focus on TDD, mainly because it can be a difficult concept to teach. When you aren’t sure how to write good tests, writing tests can feel more difficult than writing code. You may encounter a situation where you know exactly how to write the code that will solve a problem, but designing a test around it takes an hour because you’re not sure of the appropriate way to exercise the code with a test. Learning TDD will slow you down at first, but you’ll be repaid with confidence: confidence that your programs work, and confidence that if you break something, you’ll know immediately. Tests are an incredibly useful safety net for Junior developers.

You don’t need to be an expert at testing, but some familiarity with TDD will put you ahead of many other Junior applicants, especially those coming from traditional Computer Science backgrounds where test-driven development is still not always taught. Bonus points if you can eventually articulate the difference between a mock and a stub.

Your Journey Begins

You’re about to embark on a journey that might be one of the hardest, most rewarding things you’ve ever done. Don’t be afraid: be excited! The end goal is a satisfying and rewarding career and the opportunity to make the world better through technology.

No small prize.

Your future is bright. Good luck!

Просматривая статьи по проектированию ПО, я постоянно встречал тучу невиданных сокращений и вскользь упоминаемых практик разработки.

  • TDD — ну, это все знают, сначала пишем тесты, а потом остальной код.
  • BDD — что-то знакомое, вроде как, тоже тесты, но особенные.
  • TDD — снова? Так, стоп, тут речь уже не о тестах совсем. Но почему называется так же?
  • DDD — bound contexts, ubiquitous language, domain…
  • FDD — да сколько можно?
  • MDD — cерьезно, на основе диаграмм?
  • PDD — …

Подходы к разработке делятся по сложности, областям применения и целям. Думаю, настало время разобраться, зачем же они нужны, почему их так много, и как они могут быть нам полезны.

Мы начнем знакомиться с ними от самых простых до довольно сложных, рассмотрим примеры использования и плюсы и минусы каждого из них.

TDD — Test Driven Development

TDD — это методология разработки ПО, которая основывается на повторении коротких циклов разработки: изначально пишется тест, покрывающий желаемое изменение, затем пишется программный код, который реализует желаемое поведение системы и позволит пройти написанный тест. Затем проводится рефакторинг написанного кода с постоянной проверкой прохождения тестов.

Звучит просто и понятно. Многим знаком такой подход к разработке и даже сам «Uncle Bob» активно его пропагандирует:

«TDD считается одной из форм правильного метода построения приложения. Философия разработки на основе тестов заключается в том, что ваши тесты являются спецификацией того, как ваша программа должна вести себя. Если вы рассматриваете свой набор тестов как обязательную часть процесса сборки, если ваши тесты не проходят, программа не собирается, потому что она неверна. Конечно, ограничение заключается в том, что правильность вашей программы определена только как полнота ваших тестов. Тем не менее, исследования показали, что разработка, основанная на тестировании, может привести к снижению ошибок на 40-80% в производстве.»

Начав использовать TDD, вы можете почувствовать, что работаете медленнее, чем обычно. Так происходит потому что вы будете работать вне «зоны комфорта», и это вполне нормально.

После того, как вы ощутите, что написание тестов стало простой и естественной частью рабочего процесса, что вам больше не нужно думать об использовании TDD при работе над проектом, вы осознаете, что TDD влилось в вашу работу.

Эта методология позволяет добиться создания пригодного для автоматического тестирования приложения и очень хорошего покрытия кода тестами, так как ТЗ переводится на язык автоматических тестов, то есть всё, что программа должна делать, проверяется. Также TDD часто упрощает программную реализацию: исключается избыточность реализации — если компонент проходит тест, то он считается готовым.

Архитектура программных продуктов, разрабатываемых таким образом, обычно лучше (в приложениях, которые пригодны для автоматического тестирования, обычно очень хорошо распределяется ответственность между компонентами, а выполняемые сложные процедуры декомпозированы на множество простых). Стабильность работы приложения, разработанного через тестирование, выше за счёт того, что все основные функциональные возможности программы покрыты тестами и их работоспособность постоянно проверяется. Сопровождаемость проектов, где тестируется всё или практически всё, очень высока — разработчики могут не бояться вносить изменения в код, если что-то пойдёт не так, то об этом сообщат результаты автоматического тестирования.

Подробнее с принципами TDD вы можете ознакомиться, прочитав книгу Кента Бека «Экстремальное программирование. Разработка через тестирование».

TDD — Type Driven Development

Type Driven Development сокращенно пишется также, как и разработка через тестирование, поэтому обычно пишут полное название.

При разработке на основе типов ваши типы данных и сигнатуры типов являются спецификацией программы. Типы также служат формой документации, которая гарантированно обновляется.

Типы представляют из себя небольшие контрольные точки, благодаря которым, мы получаем множество мини-тестов по всему нашему приложению. Причем затраты на создание типов минимальны и актуализировать их не требуется, так как они являются частью кодовой базы.

Разработка по типу — это еще один правильный метод построения приложения. Как и в случае разработки на основе тестирования, разработка на основе типов может повысить вашу уверенность в коде и сэкономить ваше время при внесении изменений в большую кодовую базу.

Из минусов только возрастающая сложность у языков с динамической типизацией. К примеру, для JavaScript этот подход тяжелее применить, чем для TypeScript.

BDD — Behaviour Driven Development

Из-за некоторого методологического сходства TDD (Test Driven Development) и BDD (Behaviour Driven Development) часто путают даже профессионалы. В чем же отличие? Концепции обоих подходов похожи, сначала идут тесты и только потом начинается разработка, но предназначение у них совершенно разное. TDD — это больше о программировании и тестировании на уровне технической реализации продукта, когда тесты создают сами разработчики.

BDD предполагает описание тестировщиком или аналитиком пользовательских сценариев на естественном языке — если можно так выразиться, на языке бизнеса. BDD — behaviour-driven development — это разработка, основанная на описании поведения. Определенный человек(или люди) пишет описания вида «я как пользователь хочу когда нажали кнопку пуск тогда показывалось меню как на картинке» (там есть специально выделенные ключевые слова). Программисты давно написали специальные инструменты, которые подобные описания переводят в тесты (иногда совсем прозрачно для программиста). А дальше классическая разработка с тестами.

Если записывать названия тестов в виде предложений и при записи имен методов использовать лексику бизнес-домена, созданная документация становится понятна заказчикам, аналитикам и тестировщикам.

Тексты сценариев записываются в определенной форме.

Имея (прим. given — данное) какой-то контекст, Когда (прим. when) происходит событие, Тогда (прим. then) проверить результат.

Может получиться что-то подобное:

Или другой пример на русском:

+Сценарий 1: На счету есть деньги+

Имея счет с деньгами

И валидную карточку

И банкомат с наличными

Когда клиент запрашивает наличные

Тогда убедиться, что со счета было списание

И убедиться, что наличные выданы

И убедиться, что карточка возвращена

BDD подход совместно с инженерными практиками позволил нам отказаться от legacy-документации, содержащей неактуальную информацию, и получать новую документацию на лету, хранить ее вместе с проектом, что приблизило аналитиков и тестировщиков к коду.

BDD — скорее, процесс, целью которого является удешевление реализации новых фич. Еще на старте разработки мы получаем важные артефакты. Например, понятную для поддержки документацию. Эта документация дает возможность всем заинтересованным лицам сформировать свое представление о продукте и сценариях пользовательского поведения, которые должны быть реализованы в ходе итераций разработки. С BDD-подходом мы также снижаем порог входа в проект новых участников.

В чем преимущество BDD?

  • Тесты читаемые для не программистов.
  • Их легко изменять. Они часто пишутся почти на чистом английском.
  • Их может писать product owner или другие заинтересованные лица.
  • Результаты выполнения тестов более «человечные».
  • Тесты не зависят от целевого языка программирования. Миграция на другой язык сильно упрощается.

Минусы:

Но у данного подхода есть и недостатки — это долго и дорого. BDD неудобен хотя бы тем, что требует привлечения специалистов тестирования уже на этапе проработки требований, а это удлиняет цикл разработки.

Выходом из этой ситуации может оказаться выбор подходящего BDD фреймворка и правильно выстроенных процессов разработки.

Подробнее о BDD можно прочитать тут.

Многие уже давно поняли, что тестирование — это своего рода панацея от всех болезней, но так ли это на самом деле? Безусловно, основательно протестированный код работает стабильнее и предсказуемее, но тесты не избавляют нас от проблем и ошибок на этапе проектирования и постановки задач. Следующие подходы к разработке могут помочь вам с этим.

DDD — Domain Driven Design

Предметно-ориентированное проектирование не является какой-либо конкретной технологией или методологией. DDD — это набор правил, которые позволяют принимать правильные проектные решения. Данный подход позволяет значительно ускорить процесс проектирования программного обеспечения в незнакомой предметной области.

Предметно-ориентированное проектирование (реже проблемно-ориентированное, англ. Domain-driven design, DDD) — это набор принципов и схем, направленных на создание оптимальных систем объектов. Процесс разработки сводится к созданию программных абстракций, которые называются моделями предметных областей. В эти модели входит бизнес-логика, устанавливающая связь между реальными условиями области применения продукта и кодом.

Подход DDD особо полезен в ситуациях, когда разработчик не является специалистом в области разрабатываемого продукта. К примеру: программист не может знать все области, в которых требуется создать ПО, но с помощью правильного представления структуры, посредством предметно-ориентированного подхода, может без труда спроектировать приложение, основываясь на ключевых моментах и знаниях рабочей области.

В этой статье я стараюсь передать суть каждого подхода к разработке ПО, но про DDD можно написать не одну статью и охватить все нюансы в нескольких абзацах у меня не выйдет. Поэтому при объяснении я буду приводить поясняющие ссылки на самые достойные источники.

Основная цель Domain-Driven Design — это борьба со сложностью бизнес-процессов, их автоматизации и реализации в коде. «Domain» переводится как «предметная область», и именно от предметной области отталкивается разработка и проектирование в рамках данного подхода.

Ключевым понятием в DDD является «единый язык» (ubiquitous language). Ubiquitous language способствует прозрачному общению между участниками проекта. Единый он не в том смысле, что он один на все случаи жизни. Как раз наоборот. Все участники общаются на нём, всё обсуждение происходит в терминах единого языка, и все артефакты максимально должны излагаться в терминах единого языка, то есть, начиная от ТЗ, и, заканчивая кодом.

Следующим понятием является «доменная модель». Данная модель представляет из себя словарь терминов из ubiquitous language. И доменная модель, и ubiquitous language ограничены контекстом, который в Domain-Driven Design называется bounded context. Он ограничивает доменную модель таким образом, чтобы все понятия внутри него были однозначными, и все понимали, о чём идёт речь.

Пример: возьмем сущность «человек» и поместим его в контекст «публичные выступления». В этом контексте, по DDD, он становится спикером или оратором. А в контексте «семья» — мужем или братом.

Теперь про код. Важно, чтобы ваш код читался как книга, был прост и понятен всем, кто владеет единым языком проекта. Что я имею в виду?

Если в языке проекта вы используете выражения «продукт был добавлен», то следующий вариант не по DDD:

var product = new Product(‘apple’)product.save()

Почему? В коде написано, что мы создали продукт странным образом и сохранили его. Как же все таки добавить продукт? Нужно его добавить. Вот DDD код:

Product::add(‘apple’);

Архитектура:

С точки зрения Domain-Driven Design абсолютно всё равно, какую архитектуру вы выберете. Domain-Driven Design не про это, Domain-Driven Design про язык и про общение.

Но DDD почти невозможен без чистой архитектуры проекта, так как при добавлении новой функциональности или изменении старой нужно стараться сохранять гибкость и прозрачность кодовой базы. Про порты, адаптеры и луковую архитектуру можно прочитать в отличной статье. Картинка сверху как раз из нее.

Про DDD также есть статьи, которые я очень советую прочитать внимательно — тут и тут.

Что же нам это дает в итоге:

  • почти все участники команды могут читать код проекта;
  • постановка задач становится более явной;
  • баги бизнес логики становиться проще искать;
  • QA специалистам намного легче просматривать код и находить логические ошибки и баги.

Минусы:

  • требуется высокая квалификация разработчиков, особенно, на старте проекта;
  • не все клиенты готовы пойти на такие затраты, DDD нужно учиться всем участникам процесса разработки.

FDD — Features Driven Development

FDD — Эта методология (кратко именуемая FDD) была разработана Джеффом Де Люка (Jeff De Luca) и признанным гуру в области объектно-ориентированных технологий Питером Коадом (Peter Coad). FDD представляет собой попытку объединить наиболее признанные в индустрии разработки программного обеспечения методики, принимающие за основу важную для заказчика функциональность (свойства) разрабатываемого программного обеспечения. Основной целью данной методологии является разработка реального, работающего программного обеспечения систематически, в поставленные сроки.

Как и остальные адаптивные методологии, она делает основной упор на коротких итерациях, каждая из которых служит для проработки определенной части функциональности системы. Согласно FDD, одна итерация длится две недели. FDD насчитывает пять процессов. Первые три из них относятся к началу проекта:

  • разработка общей модели;
  • составление списка требуемых свойств системы;
  • планирование работы над каждым свойством;
  • проектирование каждого свойства;
  • конструирование каждого свойства.

Последние два шага необходимо делать во время каждой итерации. При этом каждый процесс разбивается на задачи и имеет критерии верификации.

Давайте поподробнее остановимся на каждом пункте.

Разработка общей модели.

Разработка начинается c анализа широты имеющегося круга задач и контекста системы. Далее для каждой моделируемой области делается более детальный разбор. Предварительные описания составляются небольшими группами и выносятся на дальнейшее обсуждение и экспертную оценку. После одна из предлагаемых моделей или их совокупность становится моделью для конкретной области. Модели каждой области задач объединяются в общую итоговую модель, которая может изменяться в течение работы.

Составление списка функций

Информация, собранная при построении общей модели, используется для составления списка функций. Функции объединяются в так называемые «области» (англ. domain), а они же в свою очередь делятся на подобласти (англ. subject areas) по функциональному признаку.

Каждая подобласть соответствует определенному бизнес-процессу, а его шаги становятся списком функций (свойств). Функции представлены в виде «действие — результат — объект», например, «проверка пароля пользователя». Разработка каждой функции должна занимать не более 2 недель, иначе задачу необходимо декомпозировать на более мелкими итерации. Список свойств в FDD – то же самое, что и product backlog в SCRUM.

План по свойствам (функциям)

Далее идет этап распределения функций среди ведущих программистов или по командам.

Проектирование функций

Для каждого свойства создается проектировочный пакет. Ведущий программист выделяет небольшую группу свойств для разработки в течение двух недель. После оставляются подробные диаграммы последовательности для каждого свойства, уточняя общую модель. Далее пишутся «заглушки» классов и методов. В этот момент мы должны сфокусироваться на дизайне программного продукта.

Реализация функции

Пишем код, убираем заглушки, тестируем.

После того, как свойство протестировано и ушло в продукт, берем следующее по приоритетам свойство, повторяем цикл дизайна/реализации.

Итого, в результате мы получаем:

  • документация по свойствам системы;
  • тщательное проектирование;
  • проще оценивать небольшие задачи;
  • тесты ориентированы на бизнес-задачи;
  • проработанный процесс создания продукта;
  • короткие итеративные циклы разработки позволяют быстрее наращивать функциональность и уменьшить количество ошибок.

Минусы:

  • FDD больше подходит для больших проектов. Небольшие команды разработки не смогут прочувствовать все преимущества данного подхода;
  • значительные затраты на внедрение и обучение.

MDD — Model Driven Development

В последнее время много внимания в публикациях отводится теме архитектуры и разработке на основе моделей MDA (Model Driven Architecture) и MDD (Model Driven Development). Не вдаваясь в подробности, выделим только ключевые моменты.

Разработка, управляемая моделями, (англ. model-driven development) — это стиль разработки программного обеспечения, когда модели становятся основными артефактами разработки, из которых генерируется код и другие артефакты.

Если говорить проще, то вся суть разработки сводится к построению необходимых диаграмм, из которых впоследствии мы генерируем рабочий код проекта.

Основная цель MDD — минимизация затрат, связанных с привязкой к конкретным системным платформам и программным инфраструктурам. Ведь основная бизнес-логика содержится в диаграммах и не сковывает нас рамками выбора языка программирования и инструментов разработки.

Давайте немного отвлечемся и вспомним про компилятор. Он преобразует язык программирования высокого уровня в эквивалентную реализацию на машинном языке. Моделью в этом случае является программа, написанная на языке высокого уровня, которая скрывает несущественные детали о ее реализации. В MDD наши диаграммы — это еще один уровень абстракции, который не позволяет нам увязнуть в деталях разработки, а посмотреть на картину в целом.

Диаграммы выступают в качестве своеобразных «чертежей», из которых различные автоматизированные и полуавтоматизированные процессы извлекают программы и соответствующие модели. Причем автоматическая генерация кода варьируется от извлечения простого скелета приложения до получения конечной кодовой базы (что сравнимо с традиционной компиляцией).

Идея MDD не нова ‑ она использовались с переменным успехом и раньше. Причиной возросшего внимания к ним в настоящее время является то, что автоматизации поддается значительно больше процессов, чем раньше. Это развитие отражается в появлении MDD-стандартов, что ведет к унификации соответствующих средств. Одним из таких стандартов является пересмотренная версия Unified Modeling Language – UML 2.0.

По стандартам Object Management Group (OMG) создание приложения состоит из следующих шагов:

  • cначала разрабатывается модель предметной области проектируемого приложения, полностью независимая от имплементирующей технологии;
  • затем она трансформируется специальным инструментом в платформо-зависимую модель;
  • наконец, она переводится в исходный код на соответствующем языке программирования.

Классический пример применения MDD, который используется уже давно, — моделирование баз данных. На основе одной концептуальной модели данных вы можете поддерживать несколько связанных с ней физических моделей для различных СУБД.

Какие преимущества мы получаем:

  • ускоряется вывод минимального жизнеспособного продукта (Minimum Viable Product) на рынок;
  • сокращается время на: генерацию каркаса приложения, модели классов, базы данных;
  • постоянно обновляемая документация;
  • для участников проекта диаграммы намного нагляднее кода.

Минусы:

  • для внедрение MMD потребуется использовать специальные программные решения, такие как Rational Software Architect, Simulink или Sirius;
  • от программистов требуются внушительные знания проектирования диаграмм;
  • значительные финансовые затраты на интеграцию данной методологии.

PDD — Panic Driven Development

Если вы пробовали методологии agile разработки, то вы наверняка пробовали и PDD. Давайте посмотрим более подробно, каковы принципы этой методологии.

Новые задачи приоритетнее старых

Всякий раз, когда в середине спринта появляется новая проблема, она имеет приоритет над любой запланированной работой. Новое всегда лучше и имеет более высокий приоритет. Странно, почему это не стало одним из принципов гибкой разработки? Нацеленность на обеспечение ценности для клиента требует, чтобы команда заботилась о новых фичах и откладывала ранее определенную работу.

Пишите столько кода, сколько нужно, чтобы решить проблему

Разработчики пишут код для жизни. Ошибки могут быть исправлены только кодом. Обсуждение дизайна и UX может только замедлить разработку. Но мы же не хотим терять драгоценное время? Сначала напишите решение, потом проверьте своё предположение по исправлению. Если исправление работает, проблема решена.

Тесты должны писаться в конце

После того, как исправление внедрено, тесты могут быть запланированы как задача, которая будет сделана в будущем. Тесты полезны, но не являются приоритетными. Вы можете позаботиться о них позже. Ручного тестирования должно быть достаточно, чтобы доказать работоспособность реализованного решения.

Доверьтесь своему инстинкту

Программирование — это искусство. Искусство имеет внутреннюю инстинктивную составляющую. Доверься своей интуиции. Напишите код. Разверните его. Только смелым улыбается удача.

Процесс гибок

Любой процесс, созданный для разработки, тестирования и выпуска программного обеспечения, — это просто набор соглашений и правил, которые не высечены в камне. Критические исправления требуют разных подходов. Ожидается, что вы согнёте процесс, чтобы выполнить задачу в срок, если этого требует бизнес.

Это процесс, управляемый менеджером

Как часть одной команды, менеджеры имеют право высказать свое мнение по вопросам развития. Рефакторинг или передовой опыт могут и должны быть отменены потребностями бизнеса. Инженеры могут высказать свое мнение, но они должны в конечном итоге принять любые потребности, которые приходят сверху.

Плюсы подхода:

  • высокая скорость разработки;
  • дешево;
  • заказчики счастливы, что наконец-то нашли толковых разработчиков.

Минусы:

  • все плюсы разобьются о технический долг и сложность проекта.

PDD своеобразный антипаттерн разработки, который, к сожалению, мы все время от времени практикуем.

Заключение

Мир agile разработки многогранен. Мы познакомились только с малой его частью, рассмотрели достаточное количество практик разработки ПО, узнали об их преимуществах и недостатках.

Надеюсь многие из вас узнали что-то новое о Driven Development практиках и теперь, встретившись лицом к лицу с аббревиатурами DDD, BDD, MDD вы не испытаете замешательства, а может даже захотите попробовать их на практике.

Понравилась статья? Поделить с друзьями:
  • Error drive power state
  • Error drive in use f перевод
  • Error downloading these libraries failed to download try again
  • Error downloading the following files stm32cube
  • Error downloading requested files transferred a partial file