Jump to content

citypaul

New Members
  • Posts

    9
  • Joined

  • Last visited

Posts posted by citypaul

  1. TDD means Test Driven Development.

     

    Like I said, refactoring is a vital part of development. I'm not arguing there. But that doesn't mean you need to unnecessarily spend hours refactoring when you could have just given a bit of thought to how you build it first.

     

    How do you estimate your workload if you have no idea what you're doing before you start? How do you break workload up between team members if nobody knows how it will be built?

     

    I find it very beneficial to just grab a notebook and sketch some stuff out before I start. Sometimes I can flush out bad ideas before I waste the time coding them, only to discover they won't work. Or, maybe something is complex and it's just easier to visualize it on paper to prevent insanity.

     

    Writing code takes time. There's no point in spending a bunch of time writing code that is inherently flawed.

     

    Test driven design is a better name for what it's really all about: http://www.drdobbs.com/architecture-and-design/test-driven-design/240168102

     

     But that doesn't mean you need to unnecessarily spend hours refactoring when you could have just given a bit of thought to how you build it first.

     

     

     

    Most refactoring steps are actually quite small. The idea is that it's hard to do two things at once - getting the actual logic and functionality right is hard enough - doing it in a neat way is even harder. So focus on getting the functionality right first, write tests that don't care about the implementation (in so far as this is possible), and then, once you've got the tests green, refactor. Because refactoring is done regularly, most refactorings are quite small and fast. It can be removing some code duplication here, renaming a few variables, extracting a method there and so on. Sometimes the refactoring step takes a minute or so and nothing more. Other times it can take a bit longer, but it's usually the fastest part of the whole process. I've heard it described with an analogy to how chefs work - if you tidy up as you go along you keep the kitchen clean and it's easy to keep making more meals. Otherwise the kitchen gets dirty - same with code - you end up with technical debt if you don't clean up after yourself. So do it often and early and you only end up tidying up small bits here and there instead of spending ages with it.

     

    How do you estimate your workload if you have no idea what you're doing before you start? How do you break workload up between team members if nobody knows how it will be built?

     

     

     

    Well, firstly we never estimate to dates. We try to break work up into quite small amounts and our features are generally quite small and focused. We work in feature squads, so there's usually only one or two developers working on a feature at any one point in time.

     

    Instead of estimating to dates, we use story points and we're quite flexible about changing these along the way. The fact is, having dates set up front usually doesn't work any way - it just gives project managers false hope and often ends up with people rushing to meet deadlines and thereby creating more technical debt, which just compounds itself. It often ends up in a finger pointing exercise in my experience.

     

    The way we work obviously involves a lot of communication and team work. We also accept that estimation is not a science and shouldn't be treated as such. Keeping the quality of the code high is a priority, so just having something functionally complete doesn't mean it means our definition of "done". All code is hosted privately on Github and has to be code reviewed before getting merged into master.

     

    I find it very beneficial to just grab a notebook and sketch some stuff out before I start. Sometimes I can flush out bad ideas before I waste the time coding them, only to discover they won't work. Or, maybe something is complex and it's just easier to visualize it on paper to prevent insanity.

     

     

    I agree with you completely. All I'm saying is I don't stick to a plan religiously and I'm always happy to move stuff around and adapt the plan if needs be. I also don't need to know every last detail before I start coding. I sketch stuff down, sure. Sometimes I think I may know which design patterns I'm going to use and so on and so forth, but I always work test first in the way I described above, and I listen to the feedback my tests are giving me. If my tests are telling me my design is bad, I change it. If they're telling me the design looks good, I carry on down that path. Sometimes I don't know how I'm going to do something and I simply make the tests pass then work out the design in the refactoring stage.

     

    >Writing code takes time. There's no point in spending a bunch of time writing code that is inherently flawed. 

     

     

     
    That's why I use TDD. Because I want to write clean code that I've got high confidence in.
     
     
    From the article:
     
    To my mind, TDD (and its more-refined cousins BDD and ATDD) are not testing methodologies at all. They're design methodologies. In fact, let's just call it Test-Driven Design to eliminate the confusion.

     

  2. The problem is where do you start? If you change one thing, you break five others. Then you fix those, and break more. It's a tough situation. It is difficult to explain in a couple of paragraphs. My best advice is to dig through some other codebases and see how other people have solved these problems. Symfony2 is a good one. They've done a really great job at decoupling their components.

     

    Most object oriented web apps these days share at least a few commonalities. Typically they will have some way of routing requests to a controller.

     

    The controller is a class, with some methods inside. The controller is like a module, and the methods are the actions of that module. For example you might have a "NewsController", with methods like "create", "edit", and "delete". A controller should be very lightweight, and just act as the middle man to tie things together. The controller should usually return a response of some kind, and this response is then usually sent to the browser and the application request is then considered complete.

     

    If it were me refactoring your app, I would start with this lifecycle process. The code that you edited in for your admin page is in dire need of refactoring. You need to have separation of concerns. Right now you have HTML all mixed in with application logic... this is a very terrible way to work. Your view logic should be entirely separate. I like Twig. Twig is a template engine which gives you a very easy way to separate your view logic. There are other ways to do it, but that is my go-to.

     

    Once you can break your view logic out, and have more reasonable controllers, then you can get to work on your original two classes that you posted.

     

    Unfortunately you're going to be making a lot of dramatic, breaking changes. But, it's all for the better!

     

    And while you're doing all that refactoring, now is as good a time as any to get going with unit testing. ;)

     

    Well despite our initial squabble, I tried to "like" this comment but the system wouldn't allow me, presumably because of my low number of posts.

     

    This is pretty accurate advice. Unit testing is a very good thing to learn. TDD is even better, which is really a way of maximising the use of automated tests to work out your design and reduce the fear of change. One step at a time though.

     

    I'd recommend reading those books I mentioned, and watch that video. This stuff won't come to you over night. It's only by reading, watching good videos and of course constantly putting these ideas into practice that things will start to "click" for you.

  3. TDD basically implies that you're coding to a design. You design what the app should do, write tests, then write code.

     

    Yes, refactoring is important and a regular part of development. But you should still have a pretty good general idea of what you're building.

     

    TDD means nothing of the sort. Test DRIVEN DESIGN. The tests are all based on business behaviour, not implementation details (so nothing, or as little as possible, about the structure of the code should be baked into the tests), and the tests are not all written at once and then made to pass with the "coding" step. You write one test. You see it fail. You make it pass and then you refactor if necessary, then you write another test. Repeat until you're done.

     

    The refactoring stage, which is a natural and essential part of the TDD process, is where you make important design decisions. You may split out an object into smaller objects, extract functions, move things up and down a hierarchy, split out new objects and so on and so forth. This is part of the process in tdd:

     

    1) Write a failing test

    2) Make the test pass

    3) Refactor if necessary

    4) Repeat until done

     

    So TDD is all about creating a design based on evidence, not following a blue print. You become much more intimately familiar with the code and the solution domain while you are working on it, so any design process that allows you to use that evidence to inform the architectural design of your code is a good thing, no?

  4. Writing code should be the last part of the process. You need a good idea of what your application is going to do before you start writing it. You can avoid lots of refactoring if you know where you're going to start with.

    No, refactoring should happen constantly, all the time. You should not design a big plan up front, because the plan will inevitably be wrong - if the plan is not perfect it causes all kinds of issues. What happens if you think of a better way during development? Do you just stick to your plan even though you can see the advantage to doing something a better way?

     

    The truth is there shouldn't really be too many discrete stages. There certainly shouldn't be a design, code, test phase - these should all happen interchangeably and be combined.

     

    I use TDD, which means that I get to refactor my code without the fear of change. This means I can start with only a minimal design (I usually have an idea in mind, but never stick to it religiously and I never design too much in advance) and I can incrementally create a great design by constantly refactoring using feedback from my tests. This is essentially a form of "evidence based design", which relies on short feedback loops that lead to constant incremental improvements. 

     

    I would never trust an upfront design. There's nothing wrong with jotting some ideas down and aiming for a certain design, but when the feedback you get from your tests (and you DO have automated tests, don't you?) tells you a design isn't working, you should adapt to that feedback and change your design now, not later.

     

    Refactoring is something that you do while you code - it's not something you do at the end, and you should be writing code AS you're designing and fleshing out your ideas.

  5. To the OP: So I found a youtube video by Robert Martin, the author of the Clean Code book I recommended above, and incidentally the guy who coined the phrase SOLID principles (literally the guy who came up with the Single Responsibility Principle), so you can't go wrong with this. I've not watched it but I'm sure it'll be a great starting point: 

     

    Edit: I've seen plenty of his videos in the past and he often starts by going on about space for no apparent reason. If he does that just skip that bit, unless you want to learn about space. I've no idea why he does that...

  6. That's a pretty douchey thing to say. Especially for somebody with 3 posts.

     

    Just an FYI....object oriented is not the end-all, be-all. If you think otherwise, it is you who is the amateur.

     

    It's the truth though. I read through a bunch of topics and read a lot of code before writing that comment. Most of the people here are learning, so you shouldn't expect too many experts. That's not to say that that will be the case for all people though of course. Some people here may be excellent

     

    And I never said object oriented is the be all and end all, but this person's code uses classes and he's talking about the single responsibility principle, so he is clearly interested in learning about good OOP design. I was merely explaining that the code he has at the moment isn't OOP, but that's ok as everyone has to learn. I started out the same way and had the same questions.

     

    To the OP: I'll have a hunt around to see if I can find a good video or something.

  7. Your classes definitely do have WAY too much responsibility.

     

    It may surprise you to learn this, but you are in no way writing object oriented code here. This is procedural code, not object oriented.

     

    The reason smaller objects are better is because it makes it far easier to change and adapt your system later. It also means you can get plenty of reusability out of objects. It's all about making them focused and giving them a clear reason to exist. Right now your code is a nightmare and I'd hate having to maintain it - adding some new functionality to this code would be horrible.

     

    Your code is also far too knowledgeable about the wider system in which it lives. You should not be accessing POST variables AT ALL in your objects like this. Instead, you should be passing things into your objects. Right now you're tied to the exact structure of the HTML form now because of this. So if you changed the form value of "vehicle_sufix" to something else, your code would break, which obviously is not what you want.

     

    It's quite hard to teach this stuff without being able to show it in practice, but essentially you would be well advised to break out your code into much smaller units.

     

    I've just read through your code a bit more. It's very messy and will be impossible to change. You're gonna get bugs all over the place - you'll change one thing and something else will break and so on and so forth.

     

    I don't have time to break your stuff apart in the way you asked. Instead, I'll recommend two books to you.

     

    Here's the first:

     

    http://www.amazon.co.uk/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882

     

    And here's the second:

     

    http://www.amazon.com/Practical-Object-Oriented-Design-Ruby-Addison-Wesley/dp/0321721330

     

    And yes, the second is a Ruby book. However, it's all about OO design and Ruby just happens to be the language chosen. I use lessons from that book at all the time.

     

    You really should read those books, as most of the people on these forums are amateurs and don't know how to write object oriented code.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.