Can someone please explain "re-usable structures" for me?
I was working on making some db objects in php, but was told I was using too much processing from the computer cause I made stuff to complicated with the below objects:
My DB objects:
$db = new Database;
$db->db_connect();
$post_content = new DbSelect;
$post_content->select('id', 'title', 'firstName', 'created', 'catName', 'tagName');
$post_content->from('content');
$post_content->join('inner');
$post_content->on('category','cat_id','id');
$post_content->where('id','1');
$post_content->order('created');
$db->db_close();
Normal PHP:
mysql_connect();
mysql_db_select();
$query = 'SELECT id, title, s_name, created, cat_name, tag_name
FROM content
JOIN INNER category, cat_id, id
WHERE id=1
ORDER created';
mysql_close();
So to reiterate my questions:
1. A quick explanation of re-usable structures?
2. why is the first method using objects "wrong"?
please note:
I'll be googling this as well as hoping for feedback
I know there a "tools" like Zend and other's that have plenty of db objects built into them, but I'm trying a DIY approach
Don't confuse object-oriented-programmed with "class-oriented" or "object-based" programming. They both, on the surface, can look like OOP but are not.
These are when you take structured code and wrap in a bunch of classes, but don't change the fundamentals of how it operates. When you program with objects in mind, but don't leverage any of the special conventions that OOP affords you (polymorphism, aggregation, encapsulation, etc). This is not OOP.
What you may have here is some of this type of code. It's a little hard to tell. Is the purpose of your DbSelect class to abstract away the raw SQL code, so that you can use connect to any database without having to rewrite your queries? (as many DBAL solutions are wont to do) Or are you doing it "just because" in an effort to look like you've achieved OOP because you turned a basic SQL query into a chain of method calls? If the latter is closer to your motivation for creating this set of classes, you probably need to think about why you're making these classes and objects in the first place.
I should note that, from what I can tell by your simple snippet, you actually have not gained anything here in the way of re-usability. Now, your design may include code that gives flexibility where I cannot see it, but kind of suspect that it isn't there. The procedural/structured snippet is really no more or less reusable than your proposed class-based one.
Whomever you were talking to has a point - developing a complex (or even simple) OOP solution can definitely have many benefits - but to do so without regard to the cost of those benefits (and there's always a cost) is foolish at best, and hazardous at worst.
I'm not sure where to start on this one. Object Oriented design is not a trivial subject, and there are many ways it can go wrong.
Essentially, you want to try to make logical indepedent objects in your application such that you can swap them out for other modules with the same interface, or reuse them in future projects. In your database example, look at PEAR::MDB2. PEAR::MDB2 abstracts the database drivers away from your application so that you don't need to worry about which specific database you're using. Today, you might be using MySQL to run your site. Tomorrow, you might switch to Postgresql. Ideally, if you use a proper OO design, you shoudn't need to change any of your code to make it work. You only need to swap out the database layer for another. (Pear::MDB2 makes this as simple as changing your db connect string)
May I suggest reading Code Complete by Steve McConnell. There's a whole chapter on Classes. While the examples are primarily C++, the concepts can be applied to any programming language, including PHP.
It seems that your solution involves more typing to achieve the same thing as the "normal" way. The string SQL would be more efficient than allocating memory for your object.
You should check out the Active Record pattern if you want to create a data abstraction layer with more features than just a select.
If you are using DbSelect objects to build queries from complicated Forms, then you are doing the right thing.
Query Object pattern
Related
I'm using PHP/MySQL...
I'm using interfaces for repositories on my Domain "command" side. This is going well. But I'm stuck on what to do on the "queries" (read) side. Do I make queries each as separate methods grouped in classes by some common similarity I find? Or do I make each query its own class? How should I go about using interfaces to make testing (and easier replacement later)?
Some places I've researched:
A github php example
An attempt to find the best decoupled approach to the read-side queries. Examples use C# unfortunately and make it a bit more challenging to grasp.
These solutions are convoluted?
We currently use the approach from the second c# link for one of our projects. If you want to use a query facade of some kind, then that's the best one I've come across. What I like most about it is that you create query objects and query handlers, and then a generic query processor does the work of passing the object to the correct handler.
Overall it works well, however it still feels like I'm working harder than I need to. I'm not really sure what this query abstraction is giving me, other than having more to maintain. Testability is often the response to that question, but I for one do not unit test queries. Unit testing in my opinion is best left for code that can potentially break/affect other code. Can a query really break anything that wouldn't be immediately apparent during regular testing? It either works or it doesn't.
If you do have a compelling reason to use a facade, then I recommend grouping the queries that are related into an interface. Such as "IBillingQueries" and "ICustomerQueries".
I quite often see in PHP, WordPress plugins specifically, that people write SQL directly in their plugins... The way I learnt things, everything should be handled in layers... So that if one day the requirements of a given layer change, I only have to worry about changing the layer that everything interfaces.
Right now I'm writing a layer to interface the database so that, if something ever changes in the way I interact with databases, all I have to do is change one layer, not X number of plugins I've created.
I feel as though this is something that other people may have come across in the past, and that my approach my be inefficient.
I'm writing classes such as
Table
Column
Row
That allow me to create database tables, columns, and rows using given objects with specific methods to handle all their functions:
$column = new \Namespace\Data\Column ( /* name, type, null/non-null, etc... */ );
$myTable = new \Namespace\Data\Table( /* name, column objects, and indexes */ );
\Namespace\TableModel.create($myTable);
My questions are...
Has someone else already written something to provide some separation between different layers?
If not, is my approach going to help at all in the long run or am I wasting my time; should I break down and hard-code the sql like everyone else?
If it is going to help writing this myself, is there any approach I could take to handle it more efficiently?
You seem to be looking for an ORM.
Here is one : http://www.doctrine-project.org/docs/orm/2.0/en/tutorials/getting-started-xml-edition.html
To be honest, I'd just hard-code the SQL, because:
Everyone else does so too. Big parts of WordPress would need to be rewritten, if they would ever wish to change from MySQL to something else. It would just be a waste of time to write your perfect layer for your plugin, if the rest of the whole system still only works with hard-coded SQL.
We don't live in a perfect world. Too much abstraction will - soon or late - end up in performance and other issues, which I don't even think of yet. Keep it simple. Also, using SQL you can benefit from some performance "hacks", which maybe won't work for other systems.
SQL is a widely accepted standard and can already be seen as abstraction layer. for example there's even the possibility to access Facebook's Graph via SQL-like syntax (see FQL). If you want to change to another data-source, you'll probably find some layer wich supports SQL-syntax anyways! In that sense, you could even say SQL already is some kind of abstraction layer.
But: if you decide to use SQL, be sure to use WordPress' $wpdb. Using that, you're on the safe side, as WordPress takes care of connecting to the database, forming the queries, etc. If, one day, WordPress will decide to change from databases to something else, they'll need to create a $wpdb-layer to that new source - for backwards compatibility. Also, many general requests already are in $wpdb as functions (such as $wpdb->insert()), so there's no direct need to hard-code SQL.
If however, you decide to use such an abstraction layer: Wikipedia has more information.
Update: I just found out that the CMS Drupal uses a database abstraction layer - but they still use SQL to form their queries, for all the different databases! I think that shows pretty clearly, how SQL can already be used as an abstraction layer.
I have a class that helps me to handle users.
For example:
$user = new User("login","passw");
$name = $user->getName();
$surname = $user->getSurname();
$table = $user->showStats();
All these methods have SQL queries inside. Some actions require only one sql queries, some - more than one. If database structure changes - it will be difficult to change all queries (class is long). So I thought to keep SQL queries away from this class. But how to do this?
After reading this question I've known about Stored Procedures. Does it mean, that now one action requires only one SQL query (call of Stored Procedure)? But how to organize separation sql from php? Should i keep sql-queries in an array? Or may be it should be an sql-queries class. If yes, how to organise this class (maybe what pattern I should learn)
This is a surprisingly large topic, but I have a few suggestions to help you on your way:
You should to look into object-relational mapping, in which an object automatically generates SQL queries. Have a look at the Object-Relational Mapping and Active Record articles for an overview. This will keep your database code minimal and make it easier if your table structure changes.
But there is no silver bullet here. If your schema changes you will have to change your queries to match. Some people prefer to deal with this by encapsulating their query logic within database views and stored procedures. This is also a good approach if you are consistent, but keep in mind that once you start writing stored procedures, they are going to be tied heavily to the particular database you are using. There is nothing wrong with using them, but they are going to make it much more difficult for you to switch databases down the road - usually not an issue, but an important aspect to keep in mind.
Anyway, whatever method you choose, I recommend that you store your database logic within several "Model" classes. It looks like you are doing something similar to this already. The basic idea is that each model encapsulates logic for a particular area of the database. Traditionally, each model would map to a single table in the DB - this is how the Ruby on Rails active record class works. It is a good strategy as it breaks down your database logic into simple little "chunks". If you keep all of the database query logic within a single file it can quickly grow out of control and become a maintenance nightmare - trust me, I've been there!
To get a better understanding of the "big picture", I recommend you spend some time reading up on web Model-View-Controller (MVC) architecture. You will also want to look at the established PHP MVC frameworks, such as CodeIgniter, Kohaha, CakePHP, etc. Even if you do not use one - although I recommend you do - it would be helpful to see how these frameworks organize your code.
I would say you should look into implementing the "repository" design pattern in your code.
A good answer to how to implement this would be too long for this space, so I'll post a couple of PHP-oriented references:
travis swicegood -- Repository Pattern in PHP
Jon Lebensold -- A Repository Pattern in PHP
You are on the right lines if you use separation of concerns to separate your business logic from your data access logic you will be in a better place.
Judging by your "there are already 2K lines of code" statement, you're either maintaining something, or midway through developing something.
Both Faust and Justin Ethier make good recommendations - "how should I separate my database access from my application code" is one of the oldest, and most-answered, questions in web development.
Personally, I like MVC - it's pretty much the default paradigm for web development, it balances maintainability with productivity, and there are a load of frameworks to support you while you're doing it.
You may, of course, decide that re-writing your app from scratch is too much effort - in which case the repository pattern is a good halfway house.
Either way, you need to read up on refactoring - getting from where you are to where you want to be is going to be tricky. I recommend the book by Fowler, as a starter.
Could you explain more about why your database schema may change? That's usually a sign of trouble ahead.....
I'm fairly new to OOP in PHP, I've made a couple of basic scripts but nothing impressive. All I've really taken from it is that it would probably be easier just make a collection of functions and include them.
The structure of classes seems to just confuse what was otherwise a simple process. And in collating everything into a class it doesn't really add any functionality.
So I'm clearly missing something. Could someone explain what functionality is added by creating classes
Classes are a notion of object-oriented design (and programming and analysis, respectively), where they are used to encapsulate data and methods.
Other object-oriented programming techniques may include features such as
information hiding,
data abstraction,
encapsulation,
modularity,
polymorphism and
inheritance
From an article .. top-15-best-practices-for-writing-super-readable-code:
Object oriented programming can help you create well structured code. But that does not mean you need to abandon procedural programming completely. Actually creating a mix of both styles can be good.
From http://java.sun.com/docs/books/tutorial/java/concepts/class.html:
In the real world, you'll often find many individual objects all of the same kind. There may be thousands of other bicycles in existence, all of the same make and model. Each bicycle was built from the same set of blueprints and therefore contains the same components. In object-oriented terms, we say that your bicycle is an instance of the class of objects known as bicycles. A class is the blueprint from which individual objects are created.
Finally, a short youtube video about the differences between the procedural and object-oriented programming paradigm ...
While it may at first look simpler to just use a set of functions and include them, classes have their strong points. Classes can store variables and those variables are there "later."
Here's an edited example from php.net
<?php
$item_name = 'Widget 22';
$item_price = 4.90;
$item_qty = 2;
$item_total = ($item_price * $item_qty);
echo "You ordered $item_qty $item_name # \$$item_price for a total of: \$$item_total.";
?>
v.s:
<?php
class Item {
protected $name, $price, $qty, $total;
function __construct($name, $price) {
$this->name = $name;
$this->price = $price;
}
function calculate($qty) {
$this->total = number_format(($this->price * $qty), 2);
}
public function __toString() {
return "You ordered ($this->qty) '$this->name'" . ($this->qty == 1 ? "" : "s") .
" at \$$this->price, for a total of: \$$this->total.";
}
}
$widget22 = new Item("Widget 22", 4.90);
$widget22->calculate(2);
echo $widget22;
?>
Another huge benefit is that you can make more of them. Say you want to calculate the price of another item and print it. Instead of having to duplicate all the fancy logic, you can just call new Item and be done.
A big advantage to OOP is code reuse. An example: Say you design a generic "Socket" class, which communicates with a server at a very low level. Then, I may come along and decide that I want to write an FTP class, which allows a user to download files while connected to an FTP server. I can "subclass" your Socket class and extend its functionality to support FTP, without rewriting your code.
Now, say John wants to write an HTTP class, to interact with HTTP servers. He, too, can subclass your Socket class to accomplish this, without rewriting the low level socket code.
Notice how in this example there was no duplication of socket code; both me and John shared it. Code duplication is bad because if there is an error in the duplicated code, the exact same bug may occur somewhere else in your code and you may not realize it.
More detailed information about classes can be found on Wikipedia.
Classes are a way to organize programs. Classes can be used to represent entities in the real world, or artifacts in our programming world, reducing the complexity of programs by allowing us to reason about them in terms of a higher granularity.
It is well-known in psychology that experts organize knowledge into "chunks" to allow them to reason more easily and quickly about their domain. Classes allow us to reason more easily and quickly about our programs.
In addition, classes allow us to group together the knowledge about an entity together with the methods/procedures/functions/operations that are naturally associated with that entity. Again, this provides a natural way to organize the information in our programs.
There are other advantages of classes, such as inheritance, but primarily classes are a cognitive way of organizing program structure to reduce the complexity.
Just a coupl months back I was posting similar questions about classes, I have been using PHP for a few years now and I really didn't see a need to use classes, they just complicated a simple process like you said, well I finally decided to jump in on the Class train and I am still learning but I am comfortable using them now and WOW I have a completely opposite way of thinking about them now, I think they are the best feature in PHP now!
I will admit they can be overkill for a small application but a large social network site like mine is far from small, it has hundreds of files and now that I am converting over to classes it is structured much better now and easiar to build, update, manage my code and other users could come in and understand my whole site a lot better now that it uses classes. Another great feature is you can break up all those functions you might have into seperate class files and use autoload() function to auto load the correct file only when the class is needed, this is great on a big project too. Classes make things more plug in play.
All I can say is it's kind of one of those things you need to dive into to see the REAL benefits of it.
I have thought exactly the same thing.
I have read a few books on OO-PHP, my favorite being PHP In Action.
Although when I read the books I thought "Hey, this is very useful and interesting information.", I have yet to use a significant amount of OO-PHP.
Simple needs like getting info from the server and JSON-ing it back really dont need OOP. Im sure it is "Best Practice", but for many people's needs it isn't practical. A few classes, like database connection, and similar data handling can be real time savers, but PHP is sometimes easier and quicker to be used only partially OO.
It would definitely be easy to code in procedural programming (that's what your simple process is called) if your website is small. But as your website grow, you will definitely need to sort things.
For example, you will need classes to act as templates for entities to the database. You might need classes to represent each page, and in a single file you might create multiple pages. Thus these are all advantages of OOP.
In another example you have like 40 over functions. You would want to group them together. Putting them in a class as static methods would definitely help. It'll clean things up so that in future when you come back to the same code, everything looks familiar to you.
I always thought the same thing until I started using classes--realizing that it is so much simpler and better.
You should create those functions that you're mentioning, but gather them all within a class. The functions can then within a class share the same variables, and therefore making it simpler when having to use the same functions multiple times.
The best example I can come up with now is connecting to a database.
Instead of having individual functions that connect, sends a query, fetching the results and closing the connection you could wrap all these functions within a class. This would allow you to communicate to the database multiple times using the same functions, without having to make loads of variables tailored for the specific use on the page.
If you're just writing procedural-style functions then slapping them together into a class you're not going to get many of the benefits of OOP. I think that the Open Closed Principle and the Dependency Inversion Principle describe some of the biggest benefits of OOP, which you wont get unless you intentionally design them into your code.
OOP isn't perfectly suited to everything, though. I think procedural programming is well suited to web development. It involves converting a (fairly) simple request into a bunch of HTML, which is a highly procedural task. If it's simpler to include a few functions, there's no point trying to shove an OOP shaped block into a procedurally shaped hole. However, I imagine that OOP would be the better option if the website was very complex.
All of the above poster have really good points. I would highly recommend the following books:
The OO Thought Process: http://www.amazon.com/Object-Oriented-Thought-Process-3rd/dp/0672330164/ref=sr_1_5?ie=UTF8&s=books&qid=1262547120&sr=8-5
PHP5 Objects, Patterns & Practice: http://www.amazon.com/PHP-Objects-Patterns-Practice-Second/dp/1590599098/ref=sr_1_3?ie=UTF8&s=books&qid=1262546817&sr=8-3
OO Design Heuristics: http://www.amazon.com/Object-Oriented-Design-Heuristics-Arthur-Riel/dp/020163385X/ref=sr_1_1?ie=UTF8&s=books&qid=1262546869&sr=8-1
To manage complexity.
Edit: Maybe I shopuld elaborate a bit more.
Programs are complex entities and many ways have been proposed historically to tame their complexity.
Procedural programming, functions, structured programming, abstract data types and object-oriented programming are just models to help programmers manage the mental effort that is required to understand a program.
Object programming will not solve everything, and certainly for a small script it is overkill, but it works great for big applications or systems.
My original answer tries to summarize the full content of the humongous Code Complete book: do your best to manage complexity and make your programs understandable for you and your successors. It's great if you think that object programming will help you in this task, but it's even better that you question its convenience and try to find better ways.
In PHP, classes can, at the very least, save you a bunch of include statements. The lazy loading of the __autoload() function is very handy. Also, you can be confident that function names in different includes won't conflict.
To go beyond that, you can start to think of creating an API around a class. Functions which are needed only by other functions within the class can be marked private. And eventually, you should be able to ignore the actual code in your classes, and just think of them as API calls.
If I call Do::stuff($a, $b) I get this response.
And that's all you need to know. You can forget how it works "under the hood" inside the class.
And then, of course, there's classes with non-static functions. These can do various interesting things that normal functions can't.
I do not have much experience using frameworks or anything so that leaves me with little experience using Models (MVC). I have no interest whatsoever in using a framework at the moment. I am working on a website and I am trying to model some objects but I'm not sure exactly how I should be designing the class.
For instance, right now I have a class with a few public members which can be accessed directly. I have started prototyping some functions (select, delete, update) but I am not sure
If these functions should be static
If these functions should accept parameters or use the class members instead
If these functions should even exist how they do currently
If the entire concept I'm going for is the right thing to do
I can't seem to find any sort of hints on the interwebs as to how to create a model class.
If you're using a factory class then all verbs are usually instance methods and the factory is instantiated with some sort of DB session.
If the verbs are member's of the entity's class select is usually a static method while update is usually an instance method and delete is usually defined both ways (IE: delete(recordID) and entity.delete())
The entire concept is the right thing to do but you're going to do it wrong. Period. Making a scalable model like this takes a lot more time and effort than people have at their disposal. I know you have no interest in using a framework but you should.
My inference from your question is that this is a low profile project, and you have enough flexibility from your boss/client/teacher that you can build it however you want. That in mind, here is what I would think about when working on this.
If MVC is a new concept to you, then Test-Driven Development is almost certainly and alien one as well. However, I first cracked into a real understanding of OOP while doing it, so I suggest you give it a try. Writing some simple unit tests first against your model classes will take you through the exercise of figuring out how those model classes are going to be used. You'll be working with the external API of each of those objects (or groups of objects if you're not a TDD purist), and that will help guide the design of the internals. Check out PHPUnit for getting started, as the documentation has some great examples as well.
I think the TDD approach will lead you to the following conclusions:
Probably not. Static data/methods are usually only useful when you absolutely need one copy of something. I find in web apps that aside from maybe a resource connection like the DB this is rarely the case.
This depends on what the function does. Keep in mind that using local variables implies side-effects, or changes in the state of the object. If the data you need to operate on should not change the state of the entire object, use a parameter and return a value. It's also easier to test these kinds of methods.
Again, writing tests for these functions that illustrate how you'll use them in the application will lead you to a conclusion one way or another about whether you need them or whether they are designed correctly. Don't be afraid to change them.
Absolutely. How else are you going to become comfortable with MVC if you don't roll your own implementation at least once? In fact, it's probably better to grasp the concepts with real experience before you move to a more professional framework. That way, you'll understand why the concepts and conventions of the framework are the way they are.
Oh, and the lack of clarity that you're finding on what a model class is, is probably due to the fact that it's the part of your application that is most customized. This is your data model and domain logic, so a lot of it is case-specific. The best resource, though, IMHO is Martin Fowler, whose excellent book Patterns of Enterprise Application Architecture goes into a lot of detail on how and why to design a particular set of "model" classes with one pattern or another. Here is the online pattern library--obviously the book is more detailed.
Hope that helps somewhat.
When using PHP, I think designing object oriented model adds extra work with little benefits - even when looking on large frameworks, it's common to just use assoc-arrays that you can get from resultsets (see f.ex. the multiparadigm approach of Zend MVC).
While Object-Relational mapping is much more established among strongly typed languages like Java, there are already tools for PHP as well (f.ex. Doctrine). You may check it out if having OO-oriented model is what you want, but be aware that OR-mapping has severe issues of it's own and might be of little use in PHP (haven't tried it myself in a dynamic language yet).
For most newly started project, picking a good framework is usually a way to go - it can save you time and promote best practices (of course after some learning time that's different for every tool out there). When using some framework, you should always try to find out the framework's / community approach to solving specific problems (like model design & data access) before experimenting on your own.
The "correct" way to abstract away data access using object-oriented concepts is a hot-button topic for a lot of people. Put another way, there are several ways to do it and there is no "one right" way.
Rolling your own works best if you are seriously upgrading an existing application. This is because you have a heap of code that is already database dependant and you have some bounds for the necessary refactoring. It also teaches you about abstracting code because a lot of refactoring involves removing (or reducing) code duplication. Once you've done this to completion, you will have a much better idea of how a data model layer should work. Or at least, should work for the way you program. And you will know what not to do next time you build one. :-)
If you're starting a new codebase and haven't worked with a framework or object layer but know you need to build one, then the best advice I can give is to be willing to build one later, and refactor the code to suit when that does happen. Yes, it will likely mean your application will get 90% rewritten a few times.
Writing an object abstraction layer is difficult and you will end up with dense code that is fairly defensive about things, and doesn't take chances. But once you've got it working, you will also know how to build robust code, because it will probably be debugged fairly thoroughly.
No because, static methods are hard to test
It depends of the parameter, life cycle, etc. Impossible to answer without seeing some code.
?
No
OOP requires at least 10 years of experience to have a better view on what is wrong/right/better/worse.
So, if you are not a OOP expert, instead of losing too much time reinventing the wheel, I would suggest:
Use a well-known framework for the technical part
Create your classes/framework for the business/functional part.
(1) Will help you be ready in no time for the classic technical part (Session, database interaction, etc.). Will avoid you to make errors others already did.
(2) This is your core business, it should be "your DNA".
Also, using a well-known/good technical framework will make you read quality code and help you progress. (Be carefull some frameworks are really of poor quality)
When you will have enough experience, you will be able to skip the technical framework part and build/customize your own... because technical framework are usually evil (They serve too many purposes). :)