шаблоны проектирования для кода, который регулярно ломается? - PullRequest
3 голосов
/ 07 марта 2012

У меня есть этот класс, который пробует несколько методов получения данных из API веб-сервисов карт Google.

Если один из методов не работает, он пытается использовать другой. и т.д.

Примерно так (псевдокод):

FUNCTION FIND_ADDRESS( house_number, postcode )

    get location co-ordinates for postcode from local database

    if location returns false, try getting location from maps service

    if map service fails, return "postcode not found", exit

    get address components using location co-ordinates

    if address components doesn't contain street name, return street name not found, exit

    if street name exists, get all address_components + location for house number, street_name and postcode

    if no results, try again without the postcode,

    if still no results, return location co-ordinates for postcode found earlier in code

END

Как видите, это очень процедурно!

Я пытаюсь придумать способы улучшить код, и я извлек весь код, пригодный для повторного использования, добавил обработку исключений, чтобы точно знать, где происходит сбой кода.

Но мне было интересно, знает ли кто-нибудь шаблон проектирования или подобное решение.

Потому что я в основном пытаюсь что-то, если мне не удается попробовать что-то еще, если мне не удается попробовать что-то еще и так далее, пока я не получу полный адрес

Есть идеи?

Ответы [ 5 ]

5 голосов
/ 07 марта 2012

Возможно, вы захотите взглянуть на Цепочку ответственности.

В объектно-ориентированном проектировании шаблон цепочки ответственности - это шаблон проектирования, состоящий из источника командных объектов и серии обрабатываемых объектов. Каждый объект обработки содержит логику, которая определяет типы объектов команд, которые он может обрабатывать; остальные передаются следующему объекту обработки в цепочке. Существует также механизм добавления новых объектов обработки в конец этой цепочки.

Таким образом, вместо множества блоков if / else или try / catch вы делаете что-то вроде

$finderChain = new AddressFinder;
$finder
    ->add(new LocalFinder)
    ->add(new MapsService)
    ->add(…);

$result = $finder->find($houseNo, $postCode);

Внутренне вы отправите $ houseNo и $ postCode в LocalFinder. Если он не находит нужные данные, то следующему элементу цепочки поручается попытаться найти нужные данные. Это повторяется до тех пор, пока не будет достигнут конец цепочки или не будут получены требуемые данные.

2 голосов
/ 07 марта 2012

Дело не в том, что он процедурный / упс / что угодно.

Если вы легко понимаете и поддерживаете код, тогда отлично. Если вы можете сделать это через 6 месяцев, тогда даже лучше.

Ваш функциональный блок выглядит так, как он есть - просто следите, насколько глубока ваша вложенность. Чем меньше, тем лучше.

2 голосов
/ 07 марта 2012

я бы попробовал что-то вроде:

public function getAddress($houseNumber,$postCode){

    // as far as i know, if the function returns a LOOSE true, the condition is true
    if($data = location.coordinates()){ 

        // $data was returned a value,  do additional parsing here

        // if you need to return early because of an error, you can in here

        //if all proccesses deem your data valid, return the data you want returned
        if(processedAsValid){
            return $some_value;
        }
    }

    //if the previous didn't return, it goes here. $data is overwritten
    //or you can use some other variable name
    if($data = maps.service()){

        //some more parsing

        return $some_other_data;
    } 

    // if non of the above was satisfied (and thus none returned yet), return a FALSE
    return FALSE;

}
0 голосов
/ 07 марта 2012

У вас есть только 6 "если", что совсем немного, я привык работать с кодом, которому нужно до 50, если программа работает нормально.Не существует концепции программного шаблона, которая бы соответствовала вашей текущей проблеме.DP - это не решение конкретной проблемы, это концепция решения повторяющейся проблемы.Шаблоны чтения помогают мне лично узнать больше решений даже социальных проблем, шаблонов кодирования, моделирования процессов, социальных проблем в парном программировании и т. Д., Он предлагает много вдумчивых идей.

0 голосов
/ 07 марта 2012

Использовать вложенный try{} catch{} блок

...