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?
Bookmarks