SitePoint Sponsor

User Tag List

Page 5 of 8 FirstFirst 12345678 LastLast
Results 101 to 125 of 190
  1. #101
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by McGruff
    Such as?

    OOP - particularly OOP combined with testing - is a much more powerful way to work. I can understand if it looks over-complicated or unecessary on first contact (I thought that when I was starting out) but statements such as above can be very misleading for people who are trying to learn. You don't have to, of course. Php is a bus you can hop on and off anywhere you like. But if you do want to learn to produce the best quality code you possibly can, OOP and testing is the way to go. We'd be selling people short to pretend that procedural is just as good or that it's all just a matter of personal preference.
    You're right about testing: if you write tests first, you'll end up with cleaner code. (most times at least)

    But I don't think OOP helps a lot. It transforms this:

    a($b);

    into:

    $b->a();

    There is ONE genuine use, and that's first class functions. In OOP, it's called the command pattern. You don't need this at all if your language supports first-class-functions.

    Can you give me one example where OOP is useful (makes the code better)?

    Well, you can't deny that a code is definatly of better quality if it uses one class to handle let's say all the news functions instead of retyping all of the code everytime you need to do something with news.
    Ehmm, yes, but now you're comparing copy-and-paste vs oo ;-). You could have created a function library instead of and oo library. No need for rewrite in either case.

  2. #102
    SitePoint Enthusiast didimo's Avatar
    Join Date
    Jan 2006
    Posts
    79
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ehmm, yes, but now you're comparing copy-and-paste vs oo ;-). You could have created a function library instead of and oo library. No need for rewrite in either case.
    from your post above its obvious u nevered programmed in other languages or worked on anything more than 1000lines of code long

    yes you can program everything in procedural (but u can also do the same thing in assembly, (or even binary)) but it just gets rediculos!

    in java for example you can create you class and dump ALL the code into the main method, itll work but itll be messy and you WONTmake friends with your fella programmers


    or if you have a fetish for brackets you can program in SCHEME, same thing the program will work but ittl be a waste of your time


    anyways this thread is about code quality now programming paradigms

  3. #103
    SitePoint Enthusiast didimo's Avatar
    Join Date
    Jan 2006
    Posts
    79
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Can you give me one example where OOP is useful (makes the code better)?
    write a multithreaded server and graphical browser in Java then write the same in procedural C and then youll see for yourself

    PHP made a complete bullocks of OO (they are nothing more than overglorified arrays)

    except for php5 which as language is quite nice and fast but lacks thousands of packages and classes that make Java and .NET languages so usefull for programmers

  4. #104
    SitePoint Addict
    Join Date
    Jan 2005
    Location
    Ireland
    Posts
    349
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by didimo
    from your post above its obvious u nevered programmed in other languages or worked on anything more than 1000lines of code long
    I couldn't make that judgement from Fenrir2's post. I personally think you jumped the gun there. You can write reusable code in procedual, there is no need to copy and paste.

    Quote Originally Posted by didimo
    yes you can program everything in procedural (but u can also do the same thing in assembly, (or even binary)) but it just gets rediculos!
    Many, many programs are written in pure procedual. C is a very popular language. No doubt messy code can be produced, it just takes skill to avoid this.

    Quote Originally Posted by didimo
    in java for example you can create you class and dump ALL the code into the main method, itll work but itll be messy and you WONTmake friends with your fella programmers
    You could, yes, as you could very well not use functions when writing in the procedual paradigm. But, why the hell would you do that? Dumping all you code in main in Java is not equivalent to procedual.

    Quote Originally Posted by didimo
    or if you have a fetish for brackets you can program in SCHEME, same thing the program will work but ittl be a waste of your time
    Scheme has many valid uses, especially in programs that are more suited in a functional programming language instead of, say, an imperative one. Brackets, prefix expressions, etc, all become quite easy to work with once you begin.

    Quote Originally Posted by didimo
    anyways this thread is about code quality now programming paradigms
    It still seems on topic considering it is being argued that OO is better quality than procedual. For the most part, I agree. Though is full OO really a neccessity or even the best solution?

  5. #105
    SitePoint Enthusiast didimo's Avatar
    Join Date
    Jan 2006
    Posts
    79
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I couldn't make that judgement from Fenrir2's post. I personally think you jumped the gun there.
    true i apologise

    Many, many programs are written in pure procedual. C is a very popular language. No doubt messy code can be produced, it just takes skill to avoid this.
    i started programming in C years ago, it still has its uses

    But, why the hell would you do that? Dumping all you code in main in Java is not equivalent to procedual.
    you wouldnt do that, thats why its an example, java forces you to think in OO php doesnt



    Dumping all you code in main in Java is not equivalent to procedual
    its as close as u will get, the main function in this case will be executed from the top down similary to C




    Though is full OO really a neccessity or even the best solution?
    no its not usually the best solution for small projects,
    in programming there are many ways to get from a to b and get the job done,
    for large web app (web apps are centerd around the request and response, this is quite different to event driven desktop apps) projects OO gets you from a to b faster as you are forced to look at the bigger picture at hand

  6. #106
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by Fenrir2
    But I don't think OOP helps a lot. It transforms this:

    a($b);

    into:

    $b->a();
    You have missed the key feature of OO...
    PHP Code:
    $table = new WithCrossLinks(new TableDisplay(new DefaultAccount())); 
    I can swap out the display mode, the data and the option of cross linking. I have flex points and I can place them wherever I want. To do that with functions, even in a functional language, would be a total mess.

    In the example above I am not passing a single function necessarily, like the command pattern, but a bundle. These functions are actually hidden. If I pass around a single function, I pass a single "skill". When I pass an object, I pass a bundle of skills, or a role.

    In object modelling we are not even that bothered about the individual functions, but in the role itself. It's the roles that last and become the language of the domain. Eventually they become powerful enough to influence the domain itself.

    This is what makes OO a real paradigm shift.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  7. #107
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by didimo
    true i apologise
    Welcome to Sitepoint .

    Quote Originally Posted by didimo
    ...gets you from a to b faster as you are forced to look at the bigger picture at hand
    I find the opposite tends to happen, but that's a whole other argument .

    I think OO gives the opportunity to work in a certain style. Once you are familiar with it, the code will appear cleaner and more logical. The same for any paradigm I guess. Certain types of datamodel look ugly to me.

    Let's probe the problem a little. Suppose OO did give better code. What feature of OO makes it "better"? After all, that is the problem, writing better code. What makes OO code look nicer?

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  8. #108
    SitePoint Enthusiast Buddha443556's Avatar
    Join Date
    Apr 2004
    Location
    FL, USA
    Posts
    87
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lastcraft
    Let's probe the problem a little. Suppose OO did give better code. What feature of OO makes it "better"? After all, that is the problem, writing better code. What makes OO code look nicer?
    The two features IMO that make OO code better for [large-scale and/or complex] projects is reusability and maintainability. Beautiful OO code doesn't necessarily equate to either reusability or maintainability though. Code will only get you so far, to get the most out OO code you need OO design IMHO. Which sort of brings us back to software architecture.

    Quote Originally Posted by Srirangan
    More than the specifics of the code .. I'ld determine the quality of a system by its architecture ..
    Simple fool to the 3rd include.

  9. #109
    SitePoint Zealot DerelictMan's Avatar
    Join Date
    Oct 2005
    Posts
    123
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Ryan Wray
    Could you expand further. I thought in Ruby it was the same situation, with a Math module being defined. The main difference being you can include this module:
    Code:
    include Math
    sqrt(144)
    This makes the code practically procedual.
    You can do the same in java, with static imports...

  10. #110
    SitePoint Addict
    Join Date
    Jan 2005
    Location
    Ireland
    Posts
    349
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You dead right you can, and suprising I knew that. I haven't worked that much in Java so I can be quite forgetful about some things.

    I personally think it would made more sense in Java if they could defined those functions without the Math class, and simply defined it in a package of Math. I know it is only semantics, but I think that is very important. Unforunetly, everything has to be wrapped in a class/interface in Java. But Math and the entry point (static void main) are 2 things straight off the top of my head that would make more sense outside of this OO constructs.

    Off Topic:


    Up Munster! If anything in the above post does not make any sense it is probably cause I have a few drinks in me and just popped home for a second before heading out again. Muuunnnnssssttteeeer!!!!!

  11. #111
    SitePoint Enthusiast didimo's Avatar
    Join Date
    Jan 2006
    Posts
    79
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Beautiful OO code doesn't necessarily equate to either reusability or maintainability though. Code will only get you so far, to get the most out OO code you need OO design IMHO. Which sort of brings us back to software architecture.
    beauty is in the eye of the beholder

    lol

  12. #112
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    yes you can program everything in procedural (but u can also do the same thing in assembly, (or even binary)) but it just gets rediculos!
    I know, but does the fact that you CAN mean that you shouldn't? :S.

    in java for example you can create you class and dump ALL the code into the main method, itll work but itll be messy and you WONTmake friends with your fella programmers
    What I mean with procedural style is that you create methods in the base class, and use these. That isn't quite the same as "dump all code in the main method". Of course the procedural style wouldn't work in Java, because it isn't meant to be used. But PHP IS meant to be procedural! That's why it is pretty easy to use it.

    or if you have a fetish for brackets you can program in SCHEME, same thing the program will work but ittl be a waste of your time
    Scheme seems pretty nice to me once you get over the parens. Actually, I'm writing this post in emacs ;-).

    write a multithreaded server and graphical browser in Java then write the same in procedural C and then youll see for yourself
    It's easier in Java, but that has nothing to do with procedural or OO programming. Do the same in Ruby, and see for yourself!


    PHP made a complete bullocks of OO (they are nothing more than overglorified arrays)

    except for php5 which as language is quite nice and fast but lacks thousands of packages and classes that make Java and .NET languages so usefull for programmers
    That's true. OO should have been there from the start to get a consistent system. What we have now is half baked OO with a procedural library.

    I can swap out the display mode, the data and the option of cross linking. I have flex points and I can place them wherever I want. To do that with functions, even in a functional language, would be a total mess.
    I assume you mean that you can replace the TableDisplay with ListDisplay (or something else). You can actually do this in a functional language. The difference is that you won't be focused on the objects, but on the operations. In Haskell (a functional language) you would do this with type classes (has not much to do with OO classes, more with the real world meaning of a class).

    But you wouldn't do it this way anyway if you use a functional style. You would separate the display part and the account part (sort of MVC). So you change the display{table|list|...} function in the display "module", and the defaultaccount in the lower level functions.
    Let's probe the problem a little. Suppose OO did give better code. What feature of OO makes it "better"? After all, that is the problem, writing better code. What makes OO code look nicer?
    I guess that it could look nicer because it would seem more familiar. With OO you are modeling the real world closer than with any other paradigm.

    Another Good Thing about OO is inheritance. Although it can be done in non-oo languages, it will not feel very natural in the sense that objects belong in a certain hierarchy (like car-porsche). If you do OO in a functional language you'll probably have multiple dispatch, which is more powerful than the traditional-OO-ish single dispatch, but it tends to be less natural. If you need multiple dispatch in a single dispatch language, you can. It is called the Visitor pattern.

    What are the essential OO things? Not public/private/protected if you ask me. Not classes either. I think the most important thing is that you assign behavior to types of objects. It doesn't matter much that you write it like this: an_object.a_method() or like this: a_method(an_object). If you can define versions of a_method for different kinds of an_object, that is OO.

    This lets you pass behavior around. You pass the objects, and therefore behavior. (The sad thing is, functional languages let you pass behavior directly).

  13. #113
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Fenrir2
    What are the essential OO things? Not public/private/protected if you ask me. Not classes either. I think the most important thing is that you assign behavior to types of objects. It doesn't matter much that you write it like this: an_object.a_method() or like this: a_method(an_object). If you can define versions of a_method for different kinds of an_object, that is OO.
    How would you define versions of a_method for different kinds of object in php without using classes? I can only define a_method() once, so bang goes polymorphism and bread-and-butter patterns like Command, ChainOfResponsibility, Observer...

  14. #114
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I didn't want to say that you can do OO easily without PHP's builtin support, but rather that the syntax doesn't matter.

    The only thing you need is a decent type system to do that, which, unfortunately, PHP has not.

    If you had first class functions, you could build much more natural versions of Command, ChainOfResponsibility and Observer. Command and Observer would simply be procs/lambdas and ChainOfResponsibility would be a list of procs/lambdas.

    I think you shouldn't want to program OOP stype functional programming. That won't work. Throw away all design patterns if you want to do functional programming. I think you'll notice that you don't need any patterns.

    Also note that PHP has first class functions to some extent with classes, and with eval, but it is too awkward to use.

    As an example, here is a (very) simple todolist manager in Ruby (Ruby supports both OO and functional/procedural programming):

    Code:
    $file = 'todo-oo.txt'
    
    class TodoEntry
      attr_accessor :text
    
      def initialize(text)
        @text = text
      end
    
      def [](search)
        @text[search]
      end
    
      def to_s
        @text
      end
    end
    
    class TodoList
      attr_accessor :entries
    
      def initialize(entries)
        @entries = entries.map do |entry|
          TodoEntry.new(entry)
        end
      end
    
      def self.load()
        TodoList.new(File.readlines($file))
      end
    
      def list(*args)
        i = 0
        for entry in @entries
          i += 1
          puts "#{i}: #{entry}"
        end
      end
    
      def add(entry)
        @entries << TodoEntry.new(entry)
        self.save
      end
    
      def remove(search)
        @entries.reject!{|entry| entry[search]}
        self.save
      end
    
      def save
        File.open($file, 'w') do |file|
          file.write(self.to_s)
        end
      end
    
      def to_s
        @entries.join("\n")
      end
    end
    
    begin
      list = TodoList.load
      list.send(ARGV[0], ARGV[1])
    rescue
      puts <<ENDDOC
    Usage:
    
    todo-func list
    todo-func add "item"
    todo-func remove "search"
    ENDDOC
    end
    And:

    Code:
    @file = 'todo-func.txt'
    
    def load
      File.readlines(@file)
    end
    
    def save(items)
      File.open(@file, 'w') do |f|
        f.write items.join("\n")
      end
    end
    
    def add(item)
      save(load << item)
    end
    
    def remove(item)
      save(load.reject{|i| i[item]})
    end
    
    def list(*args)
      i = 0
      for item in load
        i += 1
        puts "#{i}: #{item}"
      end
    end
    
    begin
      send(ARGV[0], ARGV[1])
    rescue
      puts <<ENDDOC
    Usage:
    
    todo-func list
    todo-func add "item"
    todo-func remove "search"
    ENDDOC
    end
    I really think the second version is better because it is cleaner, easier to understand and shorter. Some people will say that OOP doesn't help here because it is such as small example, does anyone care to explain why that would be the case, and why OOP doesn't help in short programs?

  15. #115
    SitePoint Addict
    Join Date
    May 2003
    Location
    The Netherlands
    Posts
    391
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Fenrir2
    ... does anyone care to explain why that would be the case, and why OOP doesn't help in short programs?
    My guess is that it is because OOP must be coming from OOD in order to be really object oriented. The code should reflect the objects in the design, not just a be bunch of classes. For a short process or a simple task that would be overdesigning IMHO.
    There’s more than one way to skin a cat.

  16. #116
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That explains what you have to do to make it work, not why it doesn't work in small examples. In my code, there are two classes, which resemble the "real" objects: TodoList and TodoEntry. If it is overdesign in small things, why wouldn't it be overdesign in bigger applications? The OO code above is nearly twice as long, and half as readable. (disclaimer: I coded it ;-)).

    Or do you mean that because big programs are hard to understand, you need to be close to the real world (eg. objects) to keep it readable?

    If you ask me, two quotes about XML also apply to OOP: "it's like violence, if it doesn't work, you're not using enough of it." (more patterns: http://www.phppatterns.com/docs/desi...ld_in_patterns) and "someone had a problem, so he used OOP, now he has two problems". (1. the original problem, 2. the OO-design problem).

    I could be wrong, but I have never seen anything, besides GUIs, where OOP is helpful.

    Also, aren't patterns a Really Bad Thing? The language should eliminate patterns, and thus make code cleaner (Don't Repeat Yourself). Or not?

  17. #117
    SitePoint Addict
    Join Date
    May 2003
    Location
    The Netherlands
    Posts
    391
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think indeed that there is a trade off in using object oriented design. While complicated tasks could benefit from it, a simple one would get harder to achieve. IMHO it's like building something yourself manually. I wouldn't go with planning and designing the process of making me a simple book shelf, but I would take the time to think how I would renovate my bathroom, probably dissecting that process into smaller steps and looking carefully how those steps are going to affect each other.

    Edit:

    I didn't say it wouldn't work. There are many ways that lead to Rome, but only one is the shortest.
    There’s more than one way to skin a cat.

  18. #118
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Fenrir2
    In my code, there are two classes, which resemble the "real" objects: TodoList and TodoEntry.
    Rather than taking your list of functions and wrapping them in objects, try thinking about what the objects you really need are.

    Entries are just strings, so there is no need to overcomplicate things by wrapping them in TodoEntry classes. Just use the string objects until you need to do things more complicated than built-in string manipulation.

    Your TodoList is basically proxying method calls to an array object (even in your "procedural" example). Considering you're exposing the array using attr_accessor anyway, there is no reason not to use it. Again, if you need something more complicated than an array, use something more complicated, but you don't need to in this simple example, so just don't overcomplicate things.

    So, now that you're not repeating things from the standard (object orientated!) library, the code is even shorter, and simpler:

    Code:
    class TodoList
      attr_accessor :entries
      
      def list
        @entries.each_index do |i|
          puts "#{i+1}: #{@entries[i]}"
        end
      end
    end
    
    list = TodoList.new
    
    File.open('todo-oo.txt', 'r') do |file|
      list.entries = file.readlines.collect { |entry| entry.chomp }
    end
    
    case ARGV[0]
    when "add"    then list.entries << ARGV[1]
    when "remove" then list.entries.delete ARGV[1]
    when "list"   then list.list
    else puts <<-ENDDOC
      Usage:
      todo-func list
      todo-func add "item"
      todo-func remove "search"
    ENDDOC
    end
    
    File.open('todo-oo.txt','w') do |file|
      list.entries.each do |entry|
        file.puts entry.chomp
      end
    end
    And it doesn't use send, so it's more secure too.

    Douglas
    Hello World

  19. #119
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Fenrir2
    I could be wrong, but I have never seen anything, besides GUIs, where OOP is helpful.
    In the domain layer OOP is very expressive. Objects can model business concepts closely. They won't translate one-to-one. The programmer will have to interpret these into code creating good, cohesive classes but it is a very powerful and flexible way to work.

    Encapsulating chunks of behaviour and data is good anywhere, in any layer though. Chunks can be edited in isolation, safe in the knowledge that you're not affecting anything else. Or, if the change does affect the public behaviour, the fact that communication betwen chunks is tightly controlled in an OOP design should make it easier to test. Some procedural code is just impossible to test. It's all over the place.

    Quote Originally Posted by Fenrir2
    Also, aren't patterns a Really Bad Thing? The language should eliminate patterns, and thus make code cleaner (Don't Repeat Yourself). Or not?
    I don't think you can avoid them. Patterns will be there whether planned or not. All that pattern theory does is to outline common problems and solutions. The theory explains the forces which might suggest a particular code structure and the consequences of taking that route. This is where OOP gets hard relative to procedural. It's like playing chess compared to playing draughts. Once you've got everything under lock and key in objects, you've got to figure out how to get them all talking to each other.

  20. #120
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by McGruff
    All that pattern theory does is to outline common problems and solutions.
    If you've read the GoF design patterns book, you'll know that not all "common problems" are common to all languages. Right at the start of the book, around page 4 I think, it talks about how not all patterns apply to all languages. For example, the Factory pattern doesn't apply to Ruby.

    So, yes, you can avoid at least some patterns by using a more powerful language.

    The argument for patterns being a "Really Bad Thing" takes this a step further: if you use a sufficiently powerful language, (or a language sufficiently close to your problem domain), you won't need to use any patterns.

    Douglas
    Hello World

  21. #121
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    OK - it's interesting to hear about other languages. Learning about design patterns is certainly on the curriculum for php though.

  22. #122
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by McGruff
    OK - it's interesting to hear about other languages. Learning about design patterns is certainly on the curriculum for php though.
    Yes, as long as they address problems in PHP, not some other language

    Douglas
    Hello World

  23. #123
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by DougBTX
    Rather than taking your list of functions and wrapping them in objects, try thinking about what the objects you really need are

    ....

    And it doesn't use send, so it's more secure too.

    Douglas
    But your code isn't functionally equivalent ;-). And, even in your example, the class isn't necessary.

    I think that we're talking about different things though. There are 3 styles: procedural, oo and functional. Your example is a mix between procedural and OO. My code is functional. (if I get the terms right) The difference is that you try not to change variables in functional style. That means that it is basically bad to do i = i + 1, BUT if you do it inside a function only (in isolation) it is ok.

    If you do that, all functions will *always* return the same things for the same arguments. So if func(34) == 3, it will always be 3 (if the function is in functional style). No mutable state. (yes, the real world is mutable, so this rule will not work for functions that perform IO). This way, the code is maintainable. If you add things, they will never interfere with other functions.

    For example, if you want to add something to the procedural solution (DougBTX's), you have a problem. Say we want to be able to mark an entry as "done". You have to change something in the middle of the code, and that might break the other features. You might want to add support for multiple lists, list merging, list deletion, etc. The only thing you have to do in the functional code, is adding more functions. You alter the existing code as little as possible.

    Also, as I explain later, it is easier to test.

    Encapsulating chunks of behaviour and data is good anywhere, in any layer though. Chunks can be edited in isolation, safe in the knowledge that you're not affecting anything else. Or, if the change does affect the public behaviour, the fact that communication betwen chunks is tightly controlled in an OOP design should make it easier to test. Some procedural code is just impossible to test. It's all over the place.
    It's the other way around if you use a good programming style. In my example, no function modifies anything, so the only thing you have to test is it's return value. Thus, it's easier to test.

    Assume you have a procedural/oo application, and you want to (unit)test it. You have to test an object, and you have to test that your object does the right thing. As a simple example, you want to test a setter method. So you write a unit test and set some property, and then you check if the getter method returns the same thing. This is simple, but it isn't as simple as this most times. You'll have to check for complex changes to object. In the functional world, this is a non-problem, because you only have to check the return values.

    Also, I think it is easier to get design right with functional style. You have high level functions, which call lower level functions, which in turn call even lower level functions, etc. The most high level functions handle IO, the lower level functions handle the data of your application, and the lowest are utility functions. In OO, there is no nice separation. You have different code styles all over the place. If you have a User object, that object has to know how to display itself (IO - high level) but it has to know if the emailaddress is correct too (utility - low level). So everything is mixed. A partial solution is MVC, where the C handles IO, the M handles data, and the V handles the user's representation of the M. This is nice, but complex, and you only have 3 levels. If you use functions, there are many levels, it is more like a continuum.

    Functions may seem non-structured, but in most languages you can put them in namespaces to prevent this (or you can use a prefix if your language doesn't have namespaces).

  24. #124
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by Fenrir2
    In Haskell (a functional language) you would do this with type classes (has not much to do with OO classes, more with the real world meaning of a class).

    But you wouldn't do it this way anyway if you use a functional style. You would separate the display part and the account part (sort of MVC). So you change the display{table|list|...} function in the display "module", and the defaultaccount in the lower level functions.
    I love Haskell (and hate the excessive brackets of most functional languages), but I wouldn't use it for a business application. You have to get too much right too early for such an ill defined domain. Functional decomposition is hard, and sensitive to detail. Details change too much in business, and roles seem to fit better. Also the double level of encapsulation of OO, both methods and classes, makes the code very fluid.

    However, this is a digression...

    Quote Originally Posted by Fenrir2
    I guess that it could look nicer because it would seem more familiar. With OO you are modeling the real world closer than with any other paradigm.
    So good code looks like the problem domain? Or at least the signal to noise is high? To me, this code is OK...
    PHP Code:
    class Clientel {
        ...

        function 
    findLapsedCustomers() {
            
    $query = new AllContacts();
            
    $query->mustHaveDoneBusiness();
            
    $query->byContactDate(new OlderThan('01-01-06'));
            return 
    $this->find($query);
        }

        protected function 
    find($query) {
            return new 
    ClientIterator(
                    
    $this->_connection->select($query->asSql()));
        }

    The problem domain of finding lapsed customers has a language that is exclusively in the method. When we start messing with the nitty gritty of SQL and iterators, it's tucked away in the generic find() method. It's in this method that the domain is querying a DB.

    I think this constant domain separation is one factor in good code. I haven't got it all figured out yet.

    Quote Originally Posted by Fenrir2
    (The sad thing is, functional languages let you pass behavior directly).
    I think functional languages suck when the problem is difficult to specify unless the writer has exception mental agility. Objects are more natural to solve business problems, but then we've already agreed objects are a poor fit for maths functions. Haskell shines here.

    To avoid making this a "what makes OO code good" thread, and concentrate more on "what makes PHP code good" (or code in general), what would people consider good procedural code?

    yours, Marcus

    p.s. Regarding OO in small apps, OO only makes sense once you have two classes. Your Entry class is pointless and would go on the first refactoring, so really you have one. If Client code uses two TodoLists, it will have to keep track of state for you with some otherwise meaningless and exposed handle. This is no problem for OO, where the type is the state container itself.

    p.p.s If you have file persistence as a Mixin, isn't a TODO list just a persistent array?

    p.p.p.s OO has easy to test stateless code too, called ValueObjects. You should use them wherever possible, but this is only usually possible about half the time. the real world contains objects with identity (Entities). That's Monad hell in a functional language, unless you are doing hit and run scripts on some other data store. Typically that's the DB or the file system.

    p.p.p.p.s You wouldn't unit test a setter, as that's pretty much declarative. More complicated behaviour changes would be tested with mocks, not by unpicking state. Besides, functional languages have side effects, saving to a DB say. You have to test that exactly the same way whatever language you use.
    Last edited by lastcraft; May 21, 2006 at 17:26.
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  25. #125
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Fenrir2
    I think it is easier to get design right with functional style. You have high level functions, which call lower level functions, which in turn call even lower level functions
    I think it is easier to get design right with object oriented style. You have high level objects, which operate on lower level objects, which in turn operate on even lower level objects. You can spin this both ways, see?

    Objects, "a bunch of related data and operations", aren't to be underestimated. The mere concept makes it worthwhile.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •