When writing code for a new system I don't want to introduce unnecessary complexity in the design that I might never have any need for. So I'm following YAGNI here, and rather refactoring as I see the need for more flexibility or as responsibilities becomes more clear. This allows me to move faster.
But there is a problem here with junior devs, in that they will not recognize when to refactor or where build out the design. They just stuff more code into the existing design.
So, what are the best ways to tackle this? Should I more often build a more future-proof design so when adding to it they have a good example to follow, even if we might never have to add anything? Or should I just go ahead with more code reviews, education, etc? Or both?
Have any of you had any experience with this type of problem? How did you solve it?
I would recommend code reviews or pair programming. It gives you the chance to educate your fellow developers and increase the overall quality.
Perhaps you begin by recognizing explicitly that part of your job is to help develop the junior devs. If you're not the boss, management should sign off on this. Management needs to recognize that your choices are to develop them now or clean up after them later, and you need management's backing for the time this will take.
Code reviews and pair programming are fine ideas. They are especially good because they are not "just for junior people"–I do both with one of my close colleagues; together we are nearly 100 years old and have more than 70 years of programming experience :-)
But there's a larger problem here: the programming methodology that enables you to be most effective (YAGNI + refactor) is not effective for your junior partners. My experience is that it takes people years to learn the benefits of YAGNI, so if you expect them just to learn your way of doing things, you are setting yourself up for disappointment.
I would encourage you to identify some methodology that you think is going to be useful with your junior partners. The particular methodology probably doesn't matter (heresy!); I've had success with composite/structured design, object-based design, algebraic specification (!), and extreme programming. But
Do pick something that has a name and some literature devoted to it, that your juniors can take pride in learning, and that is a skill they can carry to future projects.
In order to show that it is tasty, you may need to eat the dog food yourself. Pick something you can live with and be productive in.
Observe your juniors carefully and teach them a decision procedure they can use to identify when they should ask you for guidance.
Good luck!
There is a reason they are junior and you are senior.
The ability to realise when a change in design is needed is one of them.
I would carry on as you are but encourage them to come to you when things are getting difficult. You can then work with them to alter the design if needed, this will be easier for you than refactoring it and will help you pass on knowledge to your junior developers.
A very good way to show how far to build out a design is to be specify about what the design will do when built out, then write tests to cover the new functionality. When the tests pass, development is done.
You might realize along the way that you forgot to test for something. That's fine, and is useful feedback to help you specify better next time. Write the missing test(s), and only enough code to make them pass.
Then refactor. Knowing what to look for when refactoring takes a bit of practice. Start with
Is there duplication in the code we've just written that we can eliminate?
Is there duplication between what we've just written and pre-existing code?
Does the code we've just written concern itself with too many things? (I.e., should we break out collaborators?)
Repeat this a few dozen times, and it'll get easier.
Another way of looking at YAGNI is that any changes to code need to be justified.
Might it be helpful to require any commit needs an associated unit test (or BDD user story, choose your poison)? It helps to communicate your intent (you want people to think about why they are adding this feature) and you get regression tests for free.
Also gets the noobs to start thinking about modularity (usually needed to make your code testable) and will help a lot if you do need to refactor later on.
I'm all for code reviews and teaching, but I think futureproof design is also important. Maybe you could think of it in terms of you designing an API and the junior developers using the API. In this way you are the one who does the hard work that they would screw up (identifying duplicated code and eliminating it) while they do all the grunt work that isn't a productive use of your time.
Of course this has to be balanced with a need to develop your junior developers skills. Neither side of the equation can be neglected.
It may help to map out what work they will do and then verify it to help build their sense of judgement which is really what you are asking, to my mind. Pairing is one option but if you can't spare that much time then having a sort of "check point" to see how they are doing and preventing them from going down the wrong path.
Related
If I'm developing a proof-of-concept application, does it make sense to invest time in writing automated tests? This is for a personal project where I am the sole developer.
I see the only benefit of automated testing at this point as:
If the concept catches, the tests already exist.
Some of the cons related to writing automated tests for this type of project could be:
It takes valuable time to write tests for an idea that might not be worthwhile to people.
At this level, time is better spent building a demonstration of your idea.
Can anyone provide pros and cons of investing time in writing automated tests for an application in its early stages?
This whole talk from the Google Testing Automation Conference is about your question:
http://www.youtube.com/watch?v=X1jWe5rOu3g
Basically, the conclusion is that it is more important to know you are building the right thing than to build something right (build the right "it", rather than build "it" right). The most important thing is to get a proof-of-concept through and make sure that it works and is liked. If people like your thing, then they will tolerate bugs; but if they don't like your thing, it can have no bugs and they still won't like it.
TDD is not really about testing, it's about designing. Doing TDD for your application will make it have a better design (probably) than just doing it on your feeling.
Your problem is : Do you need a good design ? Design is helpful for maintainance and most devs doing TDD consider themselves in maintainance mode just after having added their 1st feature.
On a more pragmatic perspective : if you're the only dev, have very accurate specs and work on this code to do it and never return to it (nor send someone else return to it), I would say that making it work is enough.
But then don't try to get anything back from it if your POC works, and just redo it.
You can save time by doing an ugly POC and come to the conclusion that your idea is not doable.
You can save time by doing an ugly POC and understanding much better the domain you're trying to model
You cannot save time by trying to get some lines of code out of an horrible codebase.
My best advice for estimating how much effort you should put in design (because overdesigning can be a big problem, too) is : try to estimate how long will that code live
Reference : I would suggest you to make some research on the motto "Make it work, make it right, make it fast" . The question you ask is about the 2 first points but you will sooner or later ask yourself the same question about optimization (the third point)
There's no "right" answer. TDD can make your concept stronger, more resilient, easier to bang on, and help drive API development. It also takes time, and radical changes mean test changes.
It's rare you get to completely throw away "prototype" code in real life, though.
The answer depends entirely on what happens if you prove your concept. True Proof-of-Concept applications are thrown away regardless of the outcome, and the real application is written afterward if the PoC proved out. Those PoCs obviously don't need tests. But there are way too many "productized PoCs" out there. Those applications probably should have tests written right up front. The other answers you've received give you solid support for both positions, you just need to decide which type of PoC you're building.
I am doing a design and build dissertation for my final year.
Everything is more or less good, except I cant find a software methodology to fit my process.
Basically I did the implementation FIRST and then from that I used tools to reverse engineer class diagrams, ERD, etc...
I can blag that I followed the waterfall method or something, but I would rather try to find an actual Software Development Mythology which does the implementation first.
I do know that is REALLY bad and is probably non-existing, however its small project and personal use only.
any helpful suggestions are greatly appreciated.
If you didn't design it first I don't think it will fit in any DESIGN pattern...
Most of the Design patterns are focused on designing it first, to save you the trouble of ending up with a bad software poorly designed.
You can just say you did the design you reversed engineered and followed it, assuming it fits any design pattern.
If the project is small enough to excuse doing something you say is "bad," maybe it's small enough to redo in a way that's "right." Just pick a methodology, (re)design your project according to that methodology, then re-code it according to the design. That way you wouldn't have to fudge anything.
There is no real process or software model that endorses coding before anything else. Well, technically there is the "Code-like-hell" approach but that is universally condemned (and not actually even a "real" approach in that it's considered a mistake.)
(See #27: http://www.stevemcconnell.com/rdenum.htm)
Most software models and processes exist to bring engineering principles to projects, and coding before planning is not an engineering principle. Granted, it's not necessarily wrong on an incredibly small project to just go ahead and code (most people would do it that way). At the same time, it does not follow any type of process or model that is well-established or almost universally accepted.
Your best options now are to redo it, say you reverse engineered it, or try to fudge it to fit some type of model, but I can't actually endorse doing the last one as it would probably end up just becoming lying.
Read about XP: extreme programming
http://www.extremeprogramming.org/
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I work as a lone developer in a very small company. My work is quite chaotic and I'm looking for ways to make it more organized.
One problem is that my projects have practically no management. Rarely anyone asks me what I'm doing, or if I have any problems. At some point there was talk about weekly status meetings, but that's some time ago. Seems that if I'd want something like that, I would have to arrange those myself.. Sometimes I'm a bit lost on what I should do next because I don't have tasks or a clear schedule defined.
From books and articles I have found many things that might be helpful. Like having a good coding standard (there exists only a rough style guide which is somewhat outdated in my opinion), code inspections, TDD, unit testing, bug database... But in a small company it seems there are no resources or time for anything that's not essential. The fact that I work in the embedded domain seems to make things only more complicated.
I feel there's also a custom of cutting corners and doing quick hacks on short notice. This leads to unfinished and unprofessional products and bugs waiting to emerge at a later date. I would imagine they are also a pain to maintain. So, I'm about to inherit a challenging code base, doing new development that requires learning a lot of new things and I guess trying to build a process for it all at the same time. It might be rewarding in the end, but as not too experienced I'm not sure if I can pull it off.
In a small shop like this the environment is far from optimal for programming. There's many other things needed to be done occasionally like customer support, answering the phone, signing parcels, hardware testing, assembly and whatever miscellaneous tasks might appear. So you get the idea about the resources. It's not all bad (sometimes it's enlightening to solve some customer problems) and I believe it can be improved, but it's the other things that I'm really concerned.
Is it possible to have a development process in a place like this?
Would it help to have some sort of management? What kind of?
Is it possible to make quality products with small resources?
How do I convince myself and others that the company which has worked successfully for decades needs to change? What would be essential?
Maybe there's someone working in a similar shop?
Use Source Control for EVERYTHING
Develop specifications and get signoff before starting - there will be resistance, but explain it's for their own good.
Unit tests! It hurts because you just want to get it done, but this will save you in the long run.
Use bug tracking - Bugzilla or FogBugz if you can afford it.
My advice is not to be extreme. From my experience, pure agile or pure traditional will not work. Before you use any process, know what it mean to solve.
I personally use a variation of Agile RUP. I do some upfront effort such as investigate the actual needs, do high-level design with possible extension. And ask customer to sign-off some major high-level requirements.
If you work in small group, detail design or specification may not worth. Of course, if there is some libraries that are shared by many, it will be worth the trouble.
Deciding what to invest in up-front depending on its risk (likelihood and effect).
Moreover, many SW best practice is really 'best' like version control, automatic testing (to me I only used it way to early detect regression as I do not believe in TDD as driven force of the development). I suggest you read 'Pragmatic Programmer' it presents many of those techines.
As to answer you questions:
(1). Is it possible to have a development process in a place like this?
Yes, but as I say, trailer it to fit your organization.
(2). Would it help to have some sort of management? What kind of?
Management helps but no control freak. Plan what to do when: integrate, resolve conflict, dead line of some mile stone. And roughly keep them on schedule (I particularly like Scrum's sprint).
(3). Is it possible to make quality products with small resources?
Definitely as soon as the size of the work, the time to develop and the size of the team is balance. If you definition of Quality is the same with me. To me, Quality means: solve the problem it set out to in an efficient and reliable fashion.
(4). How do I convince myself and others that the company which has worked successfully for decades needs to change? What would be essential?
Point out the problems. If there are none, why change? If you want to change, you should be able to identify the problem OR potential problems. Point out the problem.
Some big one are:
Without any process, it is harder for new recruited to blend in as they must learn from observing other how to deal with things.
Without process, it is harder to work in stress.
Without schedule, it is hard to determine the progress.
Without automatic testing, it will takes more time to identify problems and regression.
Without version control, it will be harder to roll-back mistake and separation of work to each team members will be mess.
Just my though.
You need to work with the owner and setup short medium and long term goals. You will want to let them know progress even if only through email.
You will need to enforce some order on your workday or you will never get anything done (those long term goals).
Divide your day up into chunks when you can code, when you are working on hacks to keep it togther, when answering emails etc.
Definitely setup a bug tracker. This can help keep your email clean. You can even setup an email address to forward bugs to be categorized later. This is good because the bug reporters will eventually tire of the bug tracker and want to just email you the bugs anyway.
edit
And as lod3n said, source control, but you are using that already right???!!?!
Been there, done that.
The book Planning Extreme Programming helped a lot. I used 3x5 cards stuck on a wall. This kept my boss informed of my progress, helped with estimates and planning, and kept me on track. The Planning Game gives good ammo if your boss's expectations are unrealistic.
Unit testing, as others have stated, helps even if you're a sole developer. I find the TDD style valuable.
lod3n is absolutely right about Source Control.
I've gone with XP-style iterations before; you may want to establish a backlog of items (even something simple like a spreadsheet or 3x5 cards) as well.
Avoid deathmarches. Stick to 40 hours in the sense of not working overtime 2 weeks in a row. Spend extra time outside of work learning new skills - not just technologies, but principles and best practices.
Have a bug tracking system, both for defects and new features. Don't rely on your memory.
Continuous integration and an automated build can help even a single developer.
Can't emphasize the recommendation for source control enough.
I've decided I don't need unit tests because I can have automated functional/integration tests instead: because with incremental development there's no need to test before integration.
as crazy as this sounds I use scrum just because I like the concepts of sprints, and backlogs. It makes it easier to set realistic goals. Of course the idea of scrum master and team is all you but if you are working on outside projects where it is possible that you may pick up an extra team member with your backlogs it will be easy to distribute work. Maybe I just like backlogs. With scrum you will need to get someone to be the product manager to talk about the features of the product. Version control is a must at probably should be implemented b4 even worrying about a software development process. I have worked in a company that started from 2 developers and went to 12 in a year. We started with no version control and low coding standards. The changes you will need to make will be gradual so don't worry about rushing to do a 180. Set a goal to change one thing a month and find supporters of your changes to make things go smooth.
As well as the recommedations of others I'd say that if you are tight on resources but have more say over how things get done you should make good use of off the shelf and open source products and libraries. This leverages the efforts of others, saving you time, ensures your code base doesn't become too esoteric and adds to your skillset so you don't end up being an expert in something that's useless everywhere else.
First, lets make a distinction between a development process and best practices. Best practices like source control, defect tracking, unit testing, etc. are an given.
Then there is the actual development processes. I would always recommend having a process, no matter small or large the team is. The trick is finding the right process. You have a process now - it is just an ad-hoc process that doesn't seem to be working out too well for for you. Rarely can you take a textbook development process and directly apply it. What you need to do is tailor the process to your companies needs and culture. Look at as many development paradigms as you can and try to find something that is a good fit and them start molding it to your needs. You may have to try and fail with a number of different processes. Perhaps the Personal Software Process will be a good starting process, maybe an agile process, a variant of RUP? You have a lot of options, start trying them out.
You are also going to have to work with the rest of your organization - they need to be a part of the process. You may be the lone developer, but a development process involves more than the developer, it involves ever person that has a say or impact in the product.
This may not be a specific answer, but my point is that you will need some kind of process. So start researching them and trying them out and molding them to your needs until you have something that works.
Let's say that you have to implement some functionality that is not trivial (it will take at least 1 work week). You have a SDK/API/library that contains (numerous) code samples demonstrating the usage of the part of the SDK for implementing that functionality.
How do you approach learning all the samples, extract the necessary information, techniques, etc. in order to use them to implement the 'real thing'. The key questions are:
Do you use some tool for diagramming of the control flow, the interactions between the functions from the SDK, and the sample itself? Which kind of diagrams do you find useful? (I was thinking that the UML sequence diagram can be quite useful together with the debugger in this case).
How do you keep the relevant and often interrelated information about SDK/API function calls, the general structure and calls order in the sample programs that have to be used as a reference - mind maps, some plain text notes, added comments in the samples code, some refactoring of the sample code to suit your personal coding style in order to make the learning easier?
Personally I use the prototyping approach. Keep development to manageable iterations. In the beginning, those iterations are really small. As part of this, don't be afraid to throw code away and start again (everytime I say that somewhere a project manager has a heart attack).
If your particular task can't easily or reasonably be divided into really small starting tasks then start with some substitute until you get going.
You want to keep it as simple as you can (the proverbial "Hello world") just to familiarize yourself with building, deploying, debugging, what error messages look like, the simple things that can and do go wrong in the beginning, etc.
I don't go as far as using a diagramming tool sorry (I barely see the point in that for my job).
As soon as you start trying things you'll get the hang of it, even if in the beginning you have no idea of what's going on and why what you're doing works (or doesn't).
I usually compile and modify the examples, making them fit something that I need to do myself. I tend to do this while using and annotating the corresponding documents. Being a bit old school, the tool I usually use for diagramming is a pencil, or for the really complex stuff two or more colored pens.
I am by no means a seasoned programmer. In fact, I am learning C++ and I've been studying the language primarily from books. When I try to stray from the books (which happens a lot because I want to start contributing to programs like LibreOffice), for example, I find myself being lost. Furthermore, when I'm using functionality of the library, my implementations are wrong because I don't really understand how the library was created and/or why things need to be done that way. When I look at sample source code, I see how something is done, but I don't understand why it's done that way which leads to poor design of my programs. And as a result, I'm constantly guessing at how to do something and dealing with errors as I encounter them. Very unproductive and frustrating.
Going back to my book comment, two books which I have ready from cover to cover more than once are Ivor Horton's Beginning Visual C++ 2010 and Starting Out with C++: Early Objects (7th Edition). What I really loved about Ivor Horton's book is that it contained thorough explanation of why something needs to be done a certain way. For example, before any Windows programming began, lots of explanation about how Windows works was given first. Understanding how and why things work a certain way really helps in how I develop software.
So to contribute my two pennies towards answering your question. I think the best approach is to pick up well written books and sit down and begin learning about that library, API, SDK, whatever in a structured approach that offers real-world examples along with explanations as to how and why things are implemented as they are.
I don't know if I totally missed your question, but I don't think I did.
Cheers!
This was my first post on this site. Don't rip me too hard. (:
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
In pair programming, the experience of every member of the team can be spread to new member. This experience is always in sync with the code, because the "senior" of the pair knows how the code works and what the design is.
So what is the utility of design documentation in this case ?
UPDATE
I don't imply no design, I imply no documentation.
With a team which practice pair programming I think that everybody is disposable, because everybody knows the code. If the senior developer leaves, I think that there is always at least one person who knows the code, because the experience was shared before.
What if your team is larger than 2 persons?
Just because two people know a part of a system does not mean it shouldn't be documented.
And I would be glad to know that I don't have to remember every tiny detail of a system just because it it's stored nowhere else than in my head.
For a small system this might work, but as the system gets larger, your limiting yourself and your colleagues. I'd rather use the memory capacity for a new system than to remember everything of the old system.
Have you ever played "telephone?" I don't think you should play it with your codebase.
What if the senior programmer leaves the company/project?
The set of deliverables should be decided independently of whether you use pair programming or not.
Six months or two years later, all the people involved could be in a different project (or a different company). Do you want to be able to come back and use the design documentation? Then, produce it. If you don't want to come back, or the design is simple enough that with the specs and the code you can understand it without the aid of an explicit design document, then you may skip it.
But don't rely on the two people explaining the design to you one year later.
Maintenance. You can't expect the team to remain static, for there to be no new members or loss of old members. Design documentation ensures that those who are new to the project, that have to maintain it years down the line, have information on decisions that were taken, why the approach was chosen, and how it was to be implemented. It's very important for the long term success of a project to have this documentation, which can be provided via a combination of traditional documents, source comments, unit tests, and various other methods.
I don't see that pair programming makes design documentation obsolete. I immediately have to think about the Truck factor. Sure, the senior may know what the design is. But what happens when he is ill? What happens when he gets hit by a truck? What if he is fired?
Pair programming does spread knowledge, but it never hurts to document that knowledge.
Who knows about the first-written code? The answer is nobody knows, because it hasn't been written. The reason it hasn't been written is because nobody knows what to do, hence the need for a design document.
Pair programming is just two people sharing one computer. By itself, it says nothing about what kind of design methodology the pair(s) uses.
Pair programming, when taking as part of "Extreme Programming", means following the Extreme Programming guidelines for design. This typically involves gathering and coding to "user stories". These stories would then stand in place of other design documentation.
The experience of people may be in sync with the code, as you say. But the design decisions are not all captured in the code - only the choices made are there.
In my experience, to really understand why code is designed the way it is, you need to know about the design choices that were not selected, the approaches that had tried and failed etc. You can hope that the "chinese whispers" chain transmits that correctly, given that there's no record of this in the code to refresh memories or correct errors...
... or you can write some documentation on the design and how it was arrived at. That way, you avoid being taken down a dark alley by the maintenance programmers in future.
Depends what you mean by "design documentation".
If you have functional tests - especially behaviour-driven development (BDD) tests, or Fitnesse or FIT tests then they're certainly a form of "active documentation"... and they certainly have value as well as being regression tests.
If you write user stories and break them down into tasks and write those tasks on cards for pairs to do then you're doing a form of documentation...
Those are the two main forms of documentation I've used in XP teams that pair on all production code.
The only other document that I find quite handy is a half-page or so set of bullet points showing people how to set up the build environment for a development machine. You're supposed to maintain the list as you go along using it.
The code base may be so large you can't humanly remember every detail of what you were intending to implement. A reference is useful in this case.
Also, you need a design if you are interacting with other components etc.
Well if you want a spreadsheet program instead of a word processor a design doc use useful :-)
XP, pair programing, agile, etc... do not mean you do not have a plan, it is just a far less detailed plan (at the micro level) of what is going on. The use cases that the user picks are more of the design, and it is more of a living document than with other styles of design/programming.
Do not fall into the trap that because youa re doing something "cool" that you no longer need good practices - indeed this style of programming requires more discipline rather than less to be successful.
Pair programming is an opportunity for the team to avoid having to spend a large proportion of the project time on documenting everything. But the need for documentation depends on how good you are at remembering the important stuff and how good your code is. You may still want lots of documentation if the code is difficult to work with.
You could try some experiments:-
Document a couple of small parts of
the design and note how often you
have to refer to it.
Document stuff that is always a pain
to work with.
No Nor does lack of pair programming mean you need documentation. Documentation is needed! What it looks like may surprise you!
An agile team will decide when and what documentation is needed. A good rule of thumb, if no one is going to read it, don't write it. Don't get caught up in the waterfall artifact thinking by provide artifacts because the Project Manager says so.
Most think of documentation as something you do with Word. If an agile team is working properly, the code itself, with TDD (test driven development) will have a set of automated test that document and enforce the requirements. Image, documentation that is in sync with the code ... and it stays that way.
Having said that, pairing does help domain, application, practice and skill knowledge propagate through the team very quickly. Pairing also helps ensure that the team follow the engineering practices including TDD and other automated test. The results are that the application remains healthy and future change is easy to bring about.
So, bottom line, pair programming produces better documentation. It does not eliminate documentation (although you might not be able to find a Word document).
I am a pro-advocate and a fan of documentation. Pair programming does not require "one senior developer". In my experience with pair programming, developers of all levels are paired together, for the purpose of rapid development. There are many times I worked with junior developers and would trade off on the keyboard. There are many times I worked with senior architects and would trade off on the keyboard. Documentation is still necessary, especially with your core components and database.
Pair Programming only enables your coding and logical aspect.
But documentation is good practice. Always do documentation...