Using a very simple set of objects for this example in PHP.
Lets say:
ObjectA:
Properties: DescId;
Methods: getListofData();
ObjectB:
Properties: DescId;DescName;
Methods: getDescNameById();
What I want to know is what is the best way to get the DescName from ObjectB when ObjectA is the one calling the function from within a loop.
I'm thinking that I need to instantiate ObjectB (as New) and then pass in the ObjectA.DescId into the ObjectB.getDescNameById method.
For example:
class objectA {
function getListOfData(){
$myObjB= new objectB();
while ...
{
$myObjB->descId = $row["descId"];
$myDescName = $myObjB->getDescNameById();
...
$i++;
}
}
}
I'm pretty sure the above will work but I'm not sure if it is the right way, or even if there are other ways of doing this. Is there a name for this type of thing? Some one mentioned Lazy Loading. Is that what this is in PHP?
Bear in mind that your question needs some expansion.
A class is a recipe. An object is the actual dish made with that recipe.
So, if you need to know how the recipe tastes, you need to actually cook something.
At design time, you're typically thinking about the classes. I.e. When you plan a dinner, you think about what you want to serve, in terms of recipes, not in term of finished dishes. (You don't have the dishes until you cook them.) That said, you may take into account that some recipes are difficult to execute and so a risky proposition to serve.
Does that make it sense?
Some questions to ask yourself about the design:
Do you even need ObjectA, as they both store an id with the same name? (Presumably, they're tied together.)
What's the difference between the two?
Can this be combined into one object?
These depends on what the methods do and what the id actually is.
In addition, you should try to assign any required information during class b's constructor.
So:
$myObjB->descId = $row["descId"];
$myDescName = $myObjB->getDescNameById();
Might become:
$myObjB = new Object_B($row["descId"]);
$myDescName = $myObjB->get_description();
This helps keep B as self-contained as possible, which is usually one of the goals of OO.
Related
I was starting a project today and after designing the database structure and how the data would be stored etc, I started the implementation. I am doing this on php, but the language isn't really relevant here, since my doubts are more architectured related or I guess, since I'm struggling more than I thought by implenting stuff in OOP on PHP. (Recently jumped on php, I've been coding in c++ and java before).
So, I started by creating my "User" class, simple as that, few attributes, and __construct, insert, update and delete methods. Those last 3, queries to the db.
Then this doubt came to my head, and I probably know the answer myself but I just don't find out.
I can now create instances and create new Users: $user = new User("John", 34) but, what if I want to edit the user "Dave"? Or I want to show all users. That method, for example, getAllUsers() which would return all users where would be implemented? Because it doesn't really belong to the class User does it? If it did, then how I would instance that method if I don't have any User instance?
I guess, I would need a class Users, or UserCollection which would be a collection of all the users, with the methods ´getCertainUser(id)´ and ´getAllUsers()´ which would return certain User or All of them, now then I would have a User I would be able to edit, right?
That being said, my questions is, how this problem should be addressed as the way to go, Am I complicating things too much? How this should be solved 'the correct way' in OOP. The times I've handled similar problems I've never used a database, so having a collection of users was the only way to store them, but having the database which stores the users feels redundant to have that collection of users.
Thanks in advance.
First, you are doing the right thing, by challenging yourself.
Obviously, there are many ways of doing things.
I highly believe that trying to keep concerns separated as much as possible and keeping classes small and simple are always two good guidelines when you want to write code that is easy to maintain and to test.
This would be one way of doing it :
To handle Models & Structures
Entity/User (Define the properties of a user)
Collection/User (implements ArrayIterator, just a structure)
To handle communication with your repository (db).
Repository/Mysql/User (implements getAllUsers, saveUser, deleteUser, etc.)
Those classes should implements common interfaces or inherit common abstract classes (if they share common logic).
For the basic persistency operation (update, delete, create), I have a little preference of moving them in the repository class instead of the entity. I prefer to avoid using "smart" entity objects. In my mind, it makes more sense. But, there are plenty of people who would disagree (and there is really no right or wrong here).
I have a Data Model structure similar to yours, where classes represent their table counterparts. In the case of retrieving multiple of a "User" or "Categories", etc, I have a static method inside the class, that returns instances of the class. In example:
class User{
public static function fetchUsersForBusiness(Business $business){
//fetch code here into variable $users from database...
$userObjs = [];
foreach($users as $userData){
$userObjs[] = new User($userData);
}
return $userObjs;
}
}
class Business{
}
The following code would return all the users that fit a certain criteria (in this case, a business they're associated with). I then return them as the objects themselves.
I've found this model to be fairly successful, and have used it in a multitude of languages including Java, PHP, and Swift. Hope it helps you.
Im about to start a large project in PHP. I want the code to be as clean as possible so I've started learning programming with classes & objects. Question is, is this the right way to structure it?
What I was thinking is three main classes. do, get and general
In general i will have a function for connecting to database.
In do i will store all functions that is inserting or updating the database for example:
class do
{
function createUser($name){
// Do stuff to create user
}
function like($id){
// Do stuff to like the id
}
}
$do = new do;
$do->like("52");
$do->createUser("Bob");
Question is, is this the right way to do this? Will this get sloppy when there are more than 20 functions in do or get?
Thanks in advance!
Remember that an object represents a thing, a noun (and a class is the type of thing); "do" is a verb, which is a pretty big clue that it's not a good choice for an object.
In fact, here, it's more like a namespace of "vaguely action-y functions", in contrast to the "get" namespace of "vaguely retrieval-y functions". Namespaces are cool too, but they should be static classes, or actual namespaces - you never need to refer to an "instance" of one, they just sit there.
As for "general", you should never, ever, plan a catch-all like that; it's like giving up on categorising your code before you started. You might end up with one later, for things you really can't put anywhere, but you should be really disappointed if you do.
The objects in the code you've mentioned here might be:
the database connection
a user
whatever thing it is that $id represents
Note that last one: an "ID" is not a thing either, it's an identifier for finding a particular thing.
In $do->like("52");, neither $do nor "52" have any real meaning. But if "52" is the ID of a page, and a user is doing the liking, a (very simple) OO implementation might look like this:
$page = Page::getByID("52");
$current_user->like( $page );
Or perhaps:
$page = Page::getByID("52");
$page->addLike( $current_user );
Immediately, the code is more readable, and relationships between your objects become clear. And that is why OOP is such a popular paradigm for organising code.
I've stuck to the basics here to get the main idea across; a modern OOP framework would go a lot further than this in turning things into objects; for instance:
"factories" and "repositories" allow creating and loading/saving objects without that static getByID call
a db connection object would be passed into objects that needed it, rather than them assuming they can create their own, which is known as "dependency injection"
I'd say, as a personal preference, that classes and objects are a great way to go. However, you're probably going to want to change "do" and "get" into "changes" and "retrievals" or something equally meaningful to you. Using keywords as class names is considered a really evil practice.
Another question trying to verify the understanding of OOP dependencies of classes.
Although I knew PHP 4.* quite well, I have only recently restarted programming, and thus started working on OOP so please be gentle ;)
Classes should be as independent as possible I understand. So, when I have a class institute that gets information from a database, I would have to inject institute with an instance of the database class, right?:
$dbh = new database();
$a = new institute();
$a->SetDBI($dbh);
In database, I have a method pulling one record from the database, and is fed with the table table, the ID column and the actual ID of the record to be pulled.
Now, say I want one method in Institute that gets one institute. To me it would make sense to then use the database class method getone():
public function GetInstitute()
{
$record = $this->dbi->GetOneRecord('table', 'column', $this->id);
}
Is this the right way of going about it? It feel that I am still building dependencies between classes this way?
The question is: am I building dependencies that should not be here? Or is it standard practice to use methods from one class in another class, as shown in the example?
This is right. You still have some dependencies between classes, but only to a certain degree. Actually (because of PHP's weak typing), you can pass any class, and it will work as long as it implements the GetOneRecord method properly.
To make it a little more strict, you can use a base class or an interface and add type hinting to the setDBI method, but otherwise, this is the way to go.
But for the implementation detail, I'm not so sure. I see you pass a table name and column name to the database object. That is not right. You don't want your Institution to know how and where it is saved. I'd rather see that you passed an object implementing a LoadInstitution($id) method. But I find it hard to give you a solid example, because it's unclear to me what GetInstitute is meant to do in the first place.
I'm trying to replace a site written procedurally with a nice set of classes as a learning exercise.
So far, I've created a record class that basically holds one line in the database's main table.
I also created a loader class which can:
loadAllFromUser($username)
loadAllFromDate($date)
loadAllFromGame($game)
These methods grab all the valid rows from the database, pack each row into a record, and stick all the records into an array.
But what if I want to just work with one record? I took a stab at that and ended up with code that was nearly identical to my procedural original.
I also wasn't sure where that one record would go. Does my loader class have a protected record property?
I'm somewhat confused.
EDIT - also, where would I put something like the HTML template for outputting a record to the site? does that go in the record class, in the loader, or in a 3rd class?
I recommend looking into using something like Doctrine for abstracting your db-to-object stuff, other than for learning purposes.
That said, there are many ways to model this type of thing, but in general it seems like the libraries (home-grown or not) that handle it tend to move towards having, at a high level:
A class that represents an object that is mapped to the db
A class that represents the way in which that object is mapped to the db
A class that represents methods for retrieving objects from the db
Think about the different tasks that need done, and try to encapsulate them cleanly. The Law of Demeter is useful to keep in mind, but don't get too bogged down with trying to grok everything in object-oriented design theory right this moment -- it can be much more useful to think, design, code, and see where weaknesses in your designs lie yourself.
For your "work with one record, but without duplicating a bunch of code" problem, perhaps something like having your loadAllFromUser methods actually be methods that call a private method that takes (for instance) a parameter that is the number of records to be retrieved, where if that parameter is null it retrieves all the records.
You can take that a step further, and implement __call on your loader class. Assuming it can know or find out about the fields that you want to load by, you can construct the parameters to a function that does the loading programatically -- look at the common parts of your functions, see what differs, and see if you can find a way to make those different parts into function parameters, or something else that allows you to avoid repetition.
MVC is worth reading up on wrt your second question. At the least, I would probably want to have that in a separate class that expects to be passed a record to render. The record probably shouldn't care about how it's represented in html, the thing that makes markup for a record shouldn't care about how the record is gotten. In general, you probably want to try to make things as standalone as possible.
It's not an easy thing to get used to, and most of "getting good" at this sort of design is a matter of practice. For actual functionality, tests can help a lot -- say you're writing your loader class, and you know that if you call loadAllFromUser($me) that you should get an array of three specific records with your dataset (even if it's a dataset used for testing only), if you have something you can run which would call that on your loader and check for the right results, it can help you know that your code is at least right from the standpoint of behavior, if not from design -- and when you change the design you can ensure that it still behaves correctly. PHPUnit seems to be the most popular tool for this in php-land.
Hopefully this points you in a useful group of directions instead of just being confusing :) Good luck, and godspeed.
You can encapsulate the unique parts of loadAllFrom... and loadOneFrom... within utility methods:
private function loadAll($tableName) {
// fetch all records from tableName
}
private function loadOne($tableName) {
// fetch one record from tableName
}
and then you won't see so much duplication:
public function loadAllFromUser() {
return $this->loadAll("user");
}
public function loadOneFromUser() {
return $this->loadOne("user");
}
If you like, you can break it down further like so:
private function load($tableName, $all = true) {
// return all or one record from tableName
// default is all
}
you can then replace all of those methods with calls such as:
$allUsers = $loader->load("users");
$date = $loader->load("date", false);
You could check the arguments coming into your method and decide from there.
$args = func_get_args();
if(count($args) > 1)
{
//do something
}
else // do something else
Something simple liek this could work. Or you could make two seperate methods inside your class for handling each type of request much like #karim's example. Whichever works best for what you would like to do.
Hopefully I understand what you are asking though.
To answer your edit:
Typically you will want to create a view class. This will be responsible for handling the HTML output of the data. It is good practice to keep these separate. The best way to do this is by injecting your 'data class' object directly into the view class like such:
class HTMLview
{
private $data;
public function __construct(Loader $_data)
{
$this->data = $_data;
}
}
And then continue with the output now that this class holds your processed database information.
It's entirely possible and plausible that your record class can have a utility method attached to itself that knows how to load a single record, given that you provide it a piece of identifying information (such as its ID, for example).
The pattern I have been using is that an object can know how to load itself, and also provides static methods to perform "loadAll" actions, returning an array of those objects to the calling code.
So, I'm going through a lot of this myself with a small open source web app I develop as well, I wrote most of it in a crunch procedurally because it's how I knew to make a working (heh, yeah) application in the shortest amount of time - and now I'm going back through and implementing heavy OOP and MVC architecture.
An instance of class A instantiates a couple of other objects, say for example from class B:
$foo = new B();
I would like to access A's public class variables from methods within B.
Unless I'm missing something, the only way to do this is to pass the current object to the instances of B:
$foo = new B($this);
Is this best practice or is there another way to do this?
That looks fine to me, I tend to use a rule of thumb of "would someone maintaining this understand it?" and that's an easily understood solution.
If there's only one "A", you could consider using the registry pattern, see for example http://www.phppatterns.com/docs/design/the_registry
I would first check if you are not using the wrong pattern: From your application logic, should B really know about A? If B needs to know about A, a parent-child relationship seems not quite adequate. For example, A could be the child, or part of A's logic could go into a third object that is "below" B in the hierarchy (i. e. doesn't know about B).
That said, I would suggest you have a method in B to register A as a data source, or create a method in A to register B as an Observer and a matching method in B that A uses to notify B of value changes.
Similar to what Paul said, if there's only one A, you can implement that as a singleton. You can then pass the instance of A as an argument to the constructor (aggregation), with a setter method (essentially aggregation again), or you can set this relationship directly in the constructor (composition).
However, while singletons are powerful, be wary of implementing them with composition. It's nice to think that you can do it that way and get rid of a constructor argument, but it also makes it impossible to replace A with something else without a code rewrite. Peronsally, I'd stick with aggregation, even if using a singleton
$foo = new B( A::getInstance() );
$foo = new B($this);
Code like this unfortunately does not match my needs. Is there any other way to access the parent object properties?
I'll try to explain why. We write a game software and some classes have very "unusual" dependencies and influence each other in different ways. That's why code sometimes gets almost unsupportable without links to parents in every instance (sometimes even several parents from different contexts i.e. a Squad may belong to Battle and to User etc...).
And now the reason why links don't satisfy me. When I generate an output for the client side, I use a kind of serializing objects in XML. It works very nice until it meets recursive references like those links to parents. I can make them protected, but then they loose their usage i.e. (dummy example)
$this->squad->battle->getTeam($tid)->getSquad($sqid)->damageCreature(...);
The other way - to implement serialization method in every serializable class and call it inside serializer like this:
$obj->toXML($node);
$this->appendChild($node);
but that's a lot of stuff to write and to support! And sometimes i generate the objects for serializer dynamically (less traffic).
I even think about a hack: to "teach" serializer to ignore some properties in certain classess )). Huh... bad idea...
It's a long discussion, but believe me, that Registry and Observer don't fit. Are there any other ideas?