I have a large class (1500 lines, but will soon be several times that) that I'd like to split so that it fits better with SRP (and so that each file is smaller and more manageable.)
The class contains 50-100 properties, and has several different types of actions that are performed against it - one of which would be an update which in turn does several steps such as update the database, and send emails.
So I think I want 4 classes.
How should I structure the classes?
Here's a simplified version of what I have now:
class Foo {
public function __construct ($params) {}
public function update () {
$this->updateDatabase();
$this->sendEmails();
}
private function updateDatabase () {}
private function sendEmails () {}
}
$foo = new Foo($params);
$foo->update();
updateDatabase() and sendEmails () each call many other methods - hundreds of lines of code each, and they have several sibling methods doing other tasks.
A basic rewrite to use static methods
class Foo {
public function __construct ($params) {}
}
class FooUpdate {
public static function update ($fooParam) {
FooUpdateDatabase::main($fooParam);
FooSendEmails::main($fooParam);
}
}
class FooUpdateDatabase {
public static function main ($fooParam) {}
}
class FooSendEmails {
public static function main ($fooParam) {}
}
$foo = new Foo($params);
FooUpdate::update($foo);
A basic rewrite to use instantiated objects
class Foo {
public function __construct () {}
}
class FooUpdate {
private $foo;
public function __construct ($fooParam) {
$this->foo = $fooParam;
}
public function main () {
$fooTemp = FooUpdateDatabase($this->fooParam);
$fooTemp->main();
$fooTemp = FooSendEmails($this->fooParam);
$fooTemp->main();
}
}
class FooUpdateDatabase {
private $foo;
public function __construct ($fooParam) {
$this->foo = $fooParam;
}
public function main () {}
}
class FooSendEmails {
private $foo;
public function __construct ($fooParam) {
$this->foo = $fooParam;
}
public function main () {}
}
$foo = new Foo($bar, ...);
$fooTemp = new FooUpdate($foo);
$fooTemp->update();
Or should I use inheritance or traits somehow?
FooSendEmails{}, or evenFooUpdateDatabase{}Consider creating anEmailclass which can house the various methods to perform your varying actions. This would be a good opportunity for you to implement polymorphism using a Factory class to determine, say, what kind of email to send (E.g. HTML, plain-text, attachments, etc), then create the additional email type classes which implement a common interface. And what aboutFooInsertDatabase?FooSelectDatabase? Create separate classes to perform those actions?FooSendEmails()does things like build display versions of data to be inserted into the email template, and work out who the email should be sent to - actions that are unique toFoo.