如何从我的逻辑中分离查询到数据库 - 分离责任,基本上[关闭]

I'm working on a login system. I'm trying to avoid having duplicate code and also trying to separate the responsibilities as much as I can.

Lets assume I have an Authentication class which does the following:

class Authentication
{
    public function login($username, $password);

    public function logout();

}

Going down the tree a bit further, I reach a point where I need to compare the credentials the user has input with the credentials in the database.

Overall I can abstract this to a certain point, where I'd need actual unique queries for certain things.

For example, for the login function I'd need a query like:

$dbPDO->prepare("SELECT $loginUsername, FROM $tableName WHERE $loginUsername=:username");

For registrying the user I'd need a query like:

$dbPDO->prepare("INSERT INTO $tableName($loginUsername, $loginPassword, $loginEmail) VALUES (:username, :password, :email)");

And so on and so forth.

Here's my question/concern, whatever you want to call it.

Generally I build a class that does a certain thing and a certain thing only. And I don't really want to mix the queries in with the logic(so to speak).

Would it be a good idea to write a class (or something else, such as an interface, I have no idea) that would take care exclusively of the queries. Or would it be OK to have the queries mixed in with the logic?

I really hope I've explained myself in an understandable way.

A very common solution to this is the repository pattern. Basically the idea is that you try to get at close as possible to being able to treat your entities like they never are written to disk, but instead always remainder in memory.

Your repository has a bunch of different methods for finding and hydrating your entities based on the criteria (when most frameworks say models they mean entities). Your repository then implements all the logic for querying the database and setting the necessary properties on the object your repository returns. It should also hydrate related objects. Many ORMs do this part for you (the hydration). Examples of this are hibernate(Java) and doctrine2(php).

Basically your best options are to either take all the logic for going from sequel query to object and put that into a repository class or use an orm to do this for you.

In your case your authentication class should have a user repository, get the user with the given Id, and them compare the retrieved users password against the inputted one.

I think it's a good idea to have have your database queries or rather data handling methods different from the application logic. That is one of the issues that the MVC architecture addresses. If you are not familiar with MVC, you want to read it up now, and see if it fits the model you have in mind.

Here is a link if you'll like to read it up.