Repository pattern in PHP - Time & Space Complexity
When using the Repository pattern, it's important to understand how the time it takes to get data changes as the data grows.
We want to know how the number of operations grows when fetching or saving many items.
Analyze the time complexity of the following code snippet.
class UserRepository {
private array $users = [];
public function addUser(array $user): void {
$this->users[] = $user;
}
public function findUserByEmail(string $email): ?array {
foreach ($this->users as $user) {
if ($user['email'] === $email) {
return $user;
}
}
return null;
}
}
This code stores users in an array and searches for a user by email using a loop.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Looping through the users array to find a matching email.
- How many times: Up to once for each user in the array until a match is found or all checked.
As the number of users grows, the search takes longer because it may check more users.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | Up to 10 checks |
| 100 | Up to 100 checks |
| 1000 | Up to 1000 checks |
Pattern observation: The number of checks grows roughly in direct proportion to the number of users.
Time Complexity: O(n)
This means the time to find a user grows linearly with the number of users stored.
[X] Wrong: "Searching in the repository is always fast and constant time."
[OK] Correct: Because the repository uses a simple array and loops through it, the search time grows as more users are added.
Understanding how data retrieval time grows helps you explain design choices and shows you can think about efficiency in real projects.
"What if we changed the users storage from an array to a hash map keyed by email? How would the time complexity change?"
Practice
Repository pattern in PHP?Solution
Step 1: Understand the role of Repository pattern
The Repository pattern is designed to separate how data is accessed from how the business logic works.Step 2: Identify the correct purpose
Separating data access from business logic makes code cleaner and easier to maintain.Final Answer:
To separate data access logic from business logic -> Option AQuick Check:
Repository pattern = separation of concerns [OK]
- Thinking Repository connects UI directly to database
- Believing all code should be in one class
- Ignoring the use of interfaces
Solution
Step 1: Recall PHP interface syntax
Interfaces use the keywordinterfacefollowed by method declarations with parentheses and types.Step 2: Check each option
interface UserRepository { public function findUser(int $id); } correctly declares an interface with a method having a typed parameter. class UserRepository { public function findUser(int $id); } usesclassinstead ofinterface. interface UserRepository { function findUser; } misses parentheses. UserRepository interface { public function findUser(int $id); } has wrong syntax order.Final Answer:
interface UserRepository { public function findUser(int $id); } -> Option DQuick Check:
Interface syntax = interface UserRepository { public function findUser(int $id); } [OK]
- Using 'class' instead of 'interface'
- Omitting parentheses in method declaration
- Wrong keyword order in interface declaration
interface UserRepository {
public function findUser(int $id);
}
class UserRepo implements UserRepository {
public function findUser(int $id) {
return "User_" . $id;
}
}
$repo = new UserRepo();
echo $repo->findUser(5);Solution
Step 1: Understand interface and class implementation
The classUserRepoimplementsUserRepositoryand defines the methodfindUserthat returns "User_" concatenated with the id.Step 2: Trace the method call
Calling$repo->findUser(5)returns "User_5" which is then printed.Final Answer:
User_5 -> Option BQuick Check:
Method returns 'User_' + id = User_5 [OK]
- Expecting just the number 5 as output
- Confusing class name with output
- Thinking interface causes error if implemented correctly
interface ProductRepository {
public function getProduct(int $id);
}
class ProductRepo implements ProductRepository {
public function getProduct() {
return "Product";
}
}Solution
Step 1: Compare interface and class method signatures
The interface methodgetProductrequires anint $idparameter, but the class method has no parameters.Step 2: Understand PHP interface implementation rules
When implementing an interface, method signatures must match exactly, including parameters.Final Answer:
Method getProduct() missing parameter in class implementation -> Option CQuick Check:
Method signatures must match [OK]
- Ignoring parameter mismatch
- Thinking class name must match interface name
- Assuming return type is mandatory in interface
Solution
Step 1: Understand flexibility in Repository pattern
Using separate interfaces and classes for each data type allows adding new repositories without changing existing ones.Step 2: Evaluate options for maintainability
Create separate interfaces like UserRepository and ProductRepository, then implement them in separate classes supports open/closed principle: open for extension, closed for modification. Other options mix concerns or lack structure.Final Answer:
Create separate interfaces like UserRepository and ProductRepository, then implement them in separate classes -> Option AQuick Check:
Separate interfaces = flexible extension [OK]
- Putting all logic in one big class
- Using global functions instead of classes
- Avoiding interfaces reduces flexibility
Ready to prove it?
Pass the test and this pattern moves unknown
