Answer the question
In order to leave comments, you need to log in
How to separate class declaration from its implementation in php?
I apologize in advance if this is a stupid question, I googled for a long time, but did not find an answer.
Let's say we have a DataKeeper class:
class DataKeeper {
private $data;
public function setData($data) {
// реализация
}
public function getData() {
// реализация
}
public function saveData() {
// реализация
}
private function processData() {
// реализация
}
}
class DataKeeper {
public function getData()
public function setData($data)
public function saveData()
}
class FileDataKeeper implements DataKeeper
$dk = new FileDataKeeper;
Answer the question
In order to leave comments, you need to log in
interfaces.
class DataKeeper implements IDataKeeper {
private $data;
public function setData($data) {
// реализация
}
public function getData() {
// реализация
}
public function saveData() {
// реализация
}
private function processData() {
// реализация
}
}
interface IDataKeeper {
public function getData();
public function setData($data);
public function saveData();
}
In addition, if I want to change the storage implementation by replacing the FileDataKeeper class, for example, with MySQLDataKeeper, the interface and public methods will not change, but the “new FileDataKeeper” will need to be changed throughout the project.
This is the beauty of interfaces, then in the code FileDataKeeper will be used only when creating an object, and the object itself will be passed by the DataKeeper type, i.e.
$keeper = new FileDataKeeper();
$someService->setDataKeeper($keeper);
// or
$keeper = new MysqlDataKeeper();
$someService->setDataKeeper($keeper);
class SomeService
{
// ...
public function setDataKeeper(DataKeeper $keeper)
{
// ...
}
// ...
}
You can use the DataKeeper class in the code, which inside itself determines, for example, based on the application config, which specific driver to use - FileDataKeeper or MySQLDataKeeper.
In this case, the transition from one driver to another will be transparent for the application.
In general, read about design patterns.
It seems to me that:
1. As a result, you will come to an abstract class
2. All the same, you will have to create a dependency container if you do not want the parent class to know about the heirs.
abstract class DataKeeper {
protected $data;
public function setData($data) {
$this->data = $data;
}
public function getData() {
return $this->data;
}
abstract public function save()
abstract public function process()
}
class FileDataKeeper extend DataKeeper {
public function save() {
// implementation
}
public function process() {
// implementation
}
}
class Container {
protected static $classes = array();
public static function register($alias, $class) {
self::$classes[$alias] = $class;
}
public static function get($alias) {
if (!isset(self::$classes[$alias]))
throw new Exception("...");
$className = self::$classes[$alias];
return new $className();
}
}
// bootstrap.php
Container:register("dataKeeper", "FileDataKeeper");
// SomeWhere.php
$dataKeeper = Container::get("dataKeeper");
If it is needed, for informational purposes only, it is better to use phpDoc. Well, or, as advised above, an interface, but then the class name and interface name will be different (as I understand it, not exactly what you need).
interface, abstract
and in order not to specify the name of the class in your case, then read about Factories.
What problem are you solving exactly?
What is the purpose of such a class implementation?
Change the structure of your code. Or make a class that combines all storage methods.
$dkm = new DataKeeper("mysql");
$dkf = new DataKeeper("file");
> It turns out that in the project, I still need to write:
> $ dk = new FileDataKeeper;
Autoload?
// в зависимости от конфига или какого нибудь условия $storageMethod = 'имя класса'
$dk = new $storageMethod;
You are all rightly advised, but you need to combine everything:
1. To hide the implementation of a class, you need to use interfaces.
2. As for $dk = new FileDataKeeper; - then the solution to this problem is the Factory. You create another Factory class with a method, say getStorrage(); For each storage option you will have a class (FileDataKeeper, MySQLDataKeeper...). We get:
$dk = Factory::getStorage();
But getStorage() will analyze the situation and return either new FileDataKeeper() or new MySQLDataKeeper() plus its implementation will also be closed.
As a result, we give the user information about the interface (available methods) and a method for obtaining the storage class.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question