Being a good engineer is a matter of experience, knowledge, and personal philosophy / attitude. Each of these things can be individually improved upon. Intentionally analyze where you are in your career and in the predispositions of your personality. Understand where you're most lacking and always work towards improving that area.
A developer who is constantly growing is a happy developer that other people want to work with and learn from. A depressed developer stuck in a dead-end learning cycle is a liability to their team and to any project in which they’re involved.
You are not just some code-monkey. You're a problem-solver whose influence significantly impacts (for better or worse) the quality of your organization.
Here are some tips on how to become a better developer. (Special thanks to the developers on FreeNode for contributing to this list of ideas.)
Learn from advanced engineers.
I come from a time pre-internet. My friend Jeremy was the only other person that I knew who was interested in creating software. We were starved for information. We’d scour bulletin-board systems to find source-code that we could read and learn from. Much of it was too advanced for us, but that’s what we had.
Now, the internet is full of guides, documentation is easy to find, and we have screencasts that show us step-by-step how to make new applications. These are great resources and we’re lucky to have them. But, many developers forget about the value of directly learning from the work of others.
Read the code of experienced engineers and aspire to truly understand WHY they made the choices that they have. Work with others to understand. Put away your ego and just study. You’ll be surprised at how quickly you change your tactics.
Fabien Potencier is a PHP heavyweight and he’s a big name in the Symfony scene (consequently the entire PHP scene). The Symfony source is some of the best material to learn from this is available in the world of PHP. Say what you want about Symfony (or better yet, just don’t say anything about it) but there’s a lot that can be learned here.
Taylor Otwell is the engineer behind the upcoming framework Laravel 4, which has been modularized into a suite of components entitled Illuminate. He’s utilizing the power of Composer to put real control into the hands of PHP developers and to improve the quality of the codebase and communities by refusing to lock developers into a specific set of functionality. The Illuminate source is a superb resource.
Take special care to look at unit-tests as well. There’s just as much to be learned here. Unit-tests can function exceptionally as documentation for the capabilities of a project.
Learn technologies that are specifically different from those that you already know.
Do you only know how to develop with PHP? Learn Python or C#.
Only ever use traditional server-side application development techniques? Learn a JS MVC framework like EmberJS. Only use MySQL? Learn ElasticSearch or PostgreSQL.
You don’t need a use case to learn a new technology. Chances are that once you learn them you’ll discover opportunities to use them. More importantly, if you have only used a couple of programming languages, then your mind is simply not thoroughly primed to understand the variety of solutions that you have the power to implement.
If you’re relying on a specific stack (LAMP, for example) then you are literally unable to use the "right tools for the right job." The saying is, "If you only have a hammer, you tend to see every problem as a nail."
An added benefit of learning new technologies is that with every bit of knowledge gained, the next becomes increasingly easy to acquire. This is why experienced developers can pick up a new technology in a day, where a beginner could spend months. Their brains are already primed with all of the concepts necessary in much the same way that learning a 3rd spoken language is often much easier than learning your 2nd.
Join a community by attending user group meetups and IRC.
This is one of the most important aspects of becoming a better developer. You’ll be exposed to new ideas via presentations, etc. But, most importantly you’ll be exposed to intelligent and motivated individuals that fill you with the kind of fuel that propels you through the next couple of weeks of enthusiastic learning. The more regularly you attend, the larger gains you’ll see.
Maintaining a high level of motivation and energy is one of the most important aspects of improving yourself as a professional engineer. If you feel like you don’t have the time to do this sort of thing then YOU are who I’m talking to. With proper management of your brain’s chemicals and natural human tendencies you can be a lot happier and a lot more productive doing what you do.
Take an interest in design patterns and agile development.
While it’s not necessary to buy the Design Patterns bible, it’s necessary to appreciate what design patterns are and what control they give you.
Design patterns teach you both solutions and problems. There’s a good chance that with each new design pattern learned you’ll realize problems that you never considered. You’ll realize how tightly-coupled your code has been and you’ll start to realize that good software design can significantly lower the cost and THE BUSY WORK associated with long-term maintenance of an application.
The best developers are able to quickly adapt their software to changing requirements without having to deal with a bunch of the most mindless and boring types of development.
Becoming a better engineer means being less bored, solving problems faster, changing codebases faster, and being able to do more without being as exposed to the negativities of the crunch.
Don’t create ignorant self-serving opinions.
How often do you hear things like, "I hate Symfony, it’s too bloated.", "I hate ORM because it’s not as fast as my raw SQL implementations.", "I hate Rails for all of the magic." or, "I really just don’t see the point of Coffeescript?"
Frankly, someone designed these technologies for a reason. They all have their advantages and disadvantages. There's a good chance that the decisions that define these projects were based on solving problems that you haven't yet encountered and don't yet know how to plan for. They may also have philosophical differences that lead them towards a different kind of solution than you. This doesn't make their solutions wrong.
The reality is that we have different opinions not only because of the differences in our knowledge and experience but also because of the differences in the problems that we have to solve.
It’s important for engineers to have experience with a wide array of tools and to understand why to use one over another. As stated earlier, if you don’t know more than one software stack then you have no way to use the best tool for the job.
It’s certainly reasonable to dislike a technology because of it’s negatives. But, unless you’ve real-world experience then it’s possible that you just have the opinion because someone that you trusted has it or because you want to give yourself the opportunity to not feel compelled to change. Either way, this is a really bad practice.
Realize what you don’t know and embrace it. Ignorance is a problem to be solved like any other. We're professional problem-solvers, after all.
Rely on your own intelligence.
I have been a provider of IRC / forum support for various technologies for over 3 years now. This is an important point that I feel very strongly about.
You don’t install a technology, play with it for a few minutes, hit a problem, then immediately rely on the help of people on IRC or forum. The people on IRC or the forums that have the knowledge to help you have time as a limited resource. When you’re being helped by someone, they’re not able to help someone else.
Have you ever gone into an active IRC channel for a technology, asked a basic question, and have been simply ignored while other people are around asking more complex questions and getting help? It’s because these people believe that you’re plenty competent enough to solve your own problem without too much trouble and that you shouldn’t be in IRC asking and waiting for a solution. You should be studying the documentation and codebase and creating one.
The hard and fast rule is that you must ask yourself "have I really tried?" and if the answer is "no" then start there.
The real advantage of having access to these experienced individuals is in gaining perspective. If you’re new to development and an experienced developer teaches you her approach to development over the course of a few hours a week that is SIGNIFICANTLY more important than them teaching you something rudimentary like how to use the authentication system or pass variables to a view.
Anyone can learn how to do that by reading the documentation, or diving into the source, or reading the code of other people’s applications.
Documentation is a great resource when it’s available. You can usually learn the API from the API documentation and you can usually get some important perspective on how to think about application development with a particular technology from a ‘getting started’ guide or a more general documentation format.
These resources are here and they’re important. It’s important that you read through the entire documentation for a technology before asking questions in IRC, maybe even multiple times.
If you can’t find what you need then read the API documentation. EmberJS has a good example of API documentation. Here you can see classes and methods and understand what each do.
Source code itself is good documentation. Maybe if you’ve read through the guide-based documentation, api documentation, and other people’s source and question / answers on stackoverflow.com and you’re still having routing problems then you can ask for help from someone else. But, if you’re asking how to make classes load from different folders or something similarly fundamental, you should be heading directly to the source to find your answers.
The source is far more accurate at answering questions than anyone in IRC, on forums, or anywhere else. The source is the part that actually means something.
Don’t short-circuit your intelligence. You’re an engineer. Some aspects of the source etc may be difficult for you to wrap your head around but you can do it and it’s not going to take the rest of your life to understand the code either.
You may say that it just takes too long and that you’re under a deadline. You may well be under the deadline because for much of your career you’ve relied on other people to do your work for you. If you dig in and learn things on your own then you’ll have real knowledge built-up and that knowledge will be yours forever, more or less.
How to Get Help
Now that you've tried to do a good job and have exhausted the other resources it may be time to ask for some help. When doing so it's important to realize that it's rare to find experienced people that are willing to answer your question. Respect the time that these people provide as a free service.
Prepare a list of things that you've tried, all relevant source code, and the exact errors or problems that you're seeing. Read the resources that you've compiled and make sure that they all make sense. It's rude to force someone who is providing free help to do all of the discovery work necessary to be able to sufficiently answer your questions. Give them the best possible set of information from which to work and you will be appreciated and respected by everyone involved. A combination of your work and the work that others expend trying to help you can help people who are otherwise unrelated to you and your problem learn new things.
You should read What Have You Tried?.
Never call anything technical "magic".
We’re engineers. We’re supposed to be the people who denounce witchcraft and explain the unknown with rational answers and utilize thorough analysis to provide pragmatic solutions to complex problems.
We have no business being afraid of the truth. Am I the best programmer? Are you? Are either of us even CLOSE? The answer is no, not by a long-shot. But, we’re professionals. We push forward and improve our philosophy and our toolkit. That’s our job.
Computer Science is too big a field for any of us. As time moves on, specialization becomes increasingly granular and we become increasingly specialized. However, in the end we ALL benefit from a healthy philosophical approach.
We must not be afraid of the unknown. We must embrace it. That is the only way forward and in this profession, if we’re not moving forwards then we’re steadily moving backwards.
I wrote this up to answer a question on FreeNode #Laravel and I thought that someone else might find it helpful. A basic overview of how method-chaining works in PHP.
class QueryMaker
{
$table = '';
$field = '';
// this is a static method, it doesn't
// run on an object, it only runs on a class
public static function make()
{
// create an instance of class
// QueryMaker and return it
return new static();
}
// this is not static, it doesn't run on
// a class, only on an object
public function setTable($name)
{
$this->table = $name;
return $this;
}
// this is also not static
public function setField($name)
{
$this->field = $name;
return $this;
}
// again, not static, just renders
// the "query"
public function flush()
{
return "select {$this->field} from {$this->table}";
}
}
Here is the implementation with method chaining
$query = QueryMaker::make()->setTable('users')->setField('name')->flush();
Here is the implementation without method chaining
$object = new QueryMaker();
$object->setTable('users');
$object->setField('name');
$query = $object->flush();
// the output is: select name from users
The methods setTable() and setField() return $this. In that context $this is the QueryMaker object that was created by make().
Let's go step by step:
$query = QueryMaker::make()->setTable('users')->setField('name')->flush();
The static method QueryMaker::make() returns an object instantiation of the QueryMaker class.
$query = $object->setTable('users')->setField('name')->flush();
$object->table is set, setTable() returns the object instance.
$query = $object->setField('name')->flush();
$object->field is set, setField() returns the object instance.
$query = $object->flush();
The flush method is called on the object, returning the string.
Forms are often used to interact with a specific model such as a user or a blog post. However, in many circumstances a form may collect data that is related to multiple data models.
It may also have special validation requirements that have little to do with the underlying data, such as captcha and password confirmation. Consequently, it often makes sense to create a form model.
A form model represents the data needs of a form. This may be validation alone, storing values for form select drop-downs, having custom methods to generate data for the form, or managing persistent data in a session to make multi-page forms simple.
In this video I discuss modeling forms and introduce a form base model for Laravel.
More documentation and information can be found on the project's Github page.
I've written many CodeIgniter tutorials, recorded a dozen screencasts, and participated in the #codeigniter IRC support channel for years. Consequently, many people ask me why I no longer use it. I realize that this article is not particularly flattering. But, I've answered this question enough times to warrant a post, so here it is.
CodeIgniter has been the go-to framework for programmers new to PHP frameworks. It is relatively easy to use, the documentation is widely considered to be good, and there is a large support community (there are currently 140 people in the CodeIgniter IRC channel). It has stood as the most popular PHP web-development framework for years. Consequently, there are many screencasts, written tutorials, and third-party libraries available. CodeIgniter is built around the concept of legacy support. So, its design is structured around the capabilities of PHP4.
However, CI has aged poorly due to a combination of legacy support between major versions and a virtually complete lack of leadership. Despite the emphasis on legacy support, recent versions of CI require PHP 5.2. PHP 5.4 is the most modern stable release and 5.3 is now available on any reasonable host. (If your host doesn't support PHP 5.3 then jump ship as soon as possible.) By providing legacy support (changes to the framework rarely require any changes to your code-base) CodeIgniter has been unable to implement any of the features available in 5.3 that give developers more flexibility to create elegant solutions to problems.
Since CI doesn't use any of the new features, best-practices suggest that its users should avoid them in order to provide standardized code. It should be easy to find and hire a PHP developer who is versed in CodeIgniter and mismatching a bunch of code-styles is a bad way to approach that goal.
When it comes to code modularity CodeIgniter is one of the worst performers in the industry. CodeIgniter is not built using any modular design pattern so all solutions are after-thoughts that were developed by members of the community. Out-of-the-box CI supports libraries (basic classes), helpers (global function declaration), and plugins (the same as helpers, these are not used). These are all different versions of the same concept separated by intent.
There are some third-party modularity solutions available. The oldest and most powerful of these is Modular Extensions by wiredesignz. It allows the implementation of HMVC modules. Unfortunately, in order to implement this he was forced to permanently alter core system files and this makes the code brittle. Issues can easily arise from upgrading CodeIgniter. As a long-time member of the #codeigniter IRC support team I can attest to the amount of issues that users end up running into as a result of this implementation. The fault is not so much on the code that drives Modular Extensions. But, on the fact that it's essentially a hack designed to expand a system that fundamentally rejects modular code.
Another third-party system released for CodeIgniter is Sparks (getsparks.org). I was a big proponent of Sparks at first and made a number of screencasts that encouraged its use. But, it quickly became apparent that Sparks is the worst form of code modularity currently available for popular PHP frameworks. The core concept seems reasonable enough. It's a command-line tool for installing packages that pulls from git repositories, supports server caching (removal of the original repo doesn't kill the spark), and versioning. These are all good things. However, it falls flat on its face due to the fact that it can't offer more than CodeIgniter itself does. Sparks can only provide libraries, helpers and config files. This limits its function to a central repository for CodeIgniter libraries. Unfortunately, it fails at that as well due to the fact that CI developers cannot rely on the libraries that they need being available within the Sparks system. A Google search ends up being the go-to method in the end, rendering Sparks useless. It is now apparent that modular code solutions have no place in the world of CodeIgniter. These are symptoms of a greater problem.
CodeIgniter was conceived by Rick Ellis of EllisLab. It is now community supported to some extent, but still seems to wilt under its creator's needs. CodeIgniter is the platform on which EllisLab's flagship product (ExpressionEngine) is built. In part due to the preoccupation of EllisLab with ExpressionEngine change to the CodeIgniter framework has come infrequently and the magnitude of the changes have been insignificant.
CodeIgniter Reactor was released so that the community could make changes and improve the framework. Unfortunately, due to the fact that there is no strong or dedicated leader, improvement to the framework has not occurred. One could easily argue that CodeIgniter 2.0 brought only minor usability improvements at the cost of dropping PHP4 support entirely. The CodeIgniter development team is either too busy with their other projects or just not sure what CI should become. It's no longer the framework for legacy support and it begs the question, "what was the purpose of dropping that support?" as users have seemed to have gained little in exchange.
When it comes to community participation only the most daring need apply. CodeIgniter is not well unit tested. This means that there is no way to responsibly make pull-requests as you're unable to test whether or not your changes have unexpectedly broken something. There was a time when this was the standard in PHP but as a community and as an industry we're past the point where that is acceptable. The community has been trying to catch up and to create tests for CI but in the last few years very little real progress has been made as the task of retrofitting CodeIgniter with unit tests is Herculean.
In summary: CodeIgniter has proven its inability to change and it can no longer compete with the feature-set or practices found in any other modern PHP framework. When I say that CodeIgniter has died. I don't mean that nobody is using it. I'm saying that CodeIgniter has nowhere to go and can become nothing more than it is.
Solution: Don't be content exploring only a single framework. CodeIgniter is lauded to be easy to learn. It is that. But, so are other frameworks. Do your due diligence and find what best serves you and your organization. Without experimenting we can't truly understand what we prefer. It's far easier to identify strengths and weaknesses when you have something with which to compare.
I use Laravel.
UPDATED 5/21:
There has been a lot of response to this post, some of it negative. I'm going to take some liberty to clarify my position.
I made a few key mistakes while constructing this post. The first is that the title distracts from the actual information in the post. The second mistake was to advocate Laravel in this post as some have assumed political motives, which is simply not true. These mistakes have distracted and confused the issues.
The assumption that I simply became bored with CodeIgniter isn't the case, and it ignores the issues that I discuss in the post.
I acknowledge that there is responsibility inherent when one provides and promotes educational resources. However, I disagree that responsibility should embargo unpopular ideas.
I'm not interested in intellectually or emotionally strong-arming anyone. I express my ideas because I believe that there is value in that. I believe that the otherwise warm response to this post is due to many users having similar experiences and perspectives on the subject.
I value the perspectives of others and you should feel free to contribute to the lively discussion in the comments.
In this video I discuss using the Laravel source code as a valuable educational resource.
In this video I discuss the basics of embedding your application logic into Laravel's routes. We revisit the topics from the the application logic in controllers screencast and approach them a bit differently.