Я регулярно определяю классы для решения задач по нескольким причинам, ниже я приведу пример своего мышления. У меня нет никаких сомнений по поводу смешивания ОО-моделей и процедурных стилей, это часто больше отражает ваше рабочее общество, чем личную религию. Часто это имеет процедурный фасад для иерархии классов, если этого ожидают другие сопровождающие.
(Пожалуйста, извините за синтаксис PHP.)
Я разрабатываю стратегии и могу следовать общей модели. Таким образом, возможное моделирование вашей задачи может заключаться в том, чтобы заставить что-то жевать пропущенные URL-адреса. Это работает, если вы хотите значительно упростить внешнюю логику и удалить условные выражения. Это показывает, что я могу использовать DNRY для метода collect ().
// batch process method
function MunchPages( $list_of_urls )
{
foreach( $list_of_urls as $url )
{
$muncher = PageMuncher::MuncherForUrl( $url );
$muncher->gather();
$muncher->process();
}
}
// factory method encaps strategy selection
function MuncherForUrl( $url )
{
if( strpos( $url, 'facebook.com' ))
return new FacebookPageMuncher( $url );
if( ... )
return new .... ;
}
// common tasks defined in base PageMuncher
class PageMuncher
{
function gather() { /* use some curl or what */ }
function process() {}
}
class FacebookPageMuncher extends PageMuncher
{
function process() { /* I do it 'this' way for FB */ }
}
Я создаю набор подпрограмм, которые идеально спрятаны и, что еще лучше, используются совместно. Примером этого может быть наличие класса, который определяет методы панели инструментов, общие для задачи. Более конкретные задачи могут расширить набор инструментов для разработки собственного поведения.
class PageMuncherUtils
{
static function begin( $html, $context )
{
// process assertions about html and context
}
static function report_fail( $context ) {}
static function exit_retry( $context ) {}
}
// elsewhere I compose the methods in cases I don't wish to inherit them
class TwitterPageMuncher
{
function validateAnchor( $html, $context )
{
if( ! PageMuncherUtils::begin( $html, $context ))
return PageMuncherUtils::report_fail( $context );
}
}
Я хочу организовать свой код так, чтобы он сопровождал сопровождающего. Учтите, что если у меня есть хотя бы один удаленный сервис, с которым я взаимодействую, я мог бы погрузиться в разные API внутри их интерфейса и хочу сгруппировать эти подпрограммы по сходным темам. Ниже я показываю пример того, как мне нравится определять класс, определяющий общие константы, класс, определяющий основные методы обслуживания, и более конкретный класс для оповещений о погоде, потому что оповещение должно знать, как обновлять себя, и оно более специфично, чем погода сервис, но также использует константы WeatherAPI.
class WeatherAPI
{
const URL = 'http://weather.net';
const URI_TOMORROW = '/nextday/';
const URI_YESTERDAY= '/yesterday/';
const API_KEY = '123';
}
class WeatherService
{
function get( $uri ) { }
function forecast( $dateurl ) { }
function alerts( $dateurl )
{
return new WeatherAlert(
$this->get( WeatherAPI::URL.$date
."?api=".WeatherAPI::API_KEY ));
}
}
class WeatherAlert
{
function refresh() {}
}
// exercise:
$alert = WeatherService::alerts( WeatherAPI::URI_TOMORROW );
$alert->refresh();