为定期中断的代码设计模式


design patterns for code that breaks regularly?

我有一个类,它尝试从Google地图web服务API获取数据的多种方法。

如果一种方法失败,它会尝试另一种方法。等

类似这样的东西(伪代码):

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

正如你所看到的,这是非常程序化的!

我正在努力想办法改进代码,我已经将所有可重用的代码外部化,添加了异常处理,以准确地知道代码在哪里失败。

但我想知道是否有人知道设计模式或类似的解决方案。

因为我基本上是在尝试一些东西,如果它尝试其他东西失败,如果它试图其他东西失败等等,直到我得到一个完整的地址

有什么想法吗?

您可能需要了解责任链。

在面向对象设计中,责任链模式是一种由命令对象源和一系列处理对象组成的设计模式。每个处理对象都包含定义其可以处理的命令对象类型的逻辑;其余的传递给链中的下一个处理对象。还存在一种机制,用于将新的处理对象添加到此链的末尾。

因此,与其有很多if/else或try/catch块,不如做一些类似的事情

$finderChain = new AddressFinder;
$finder
    ->add(new LocalFinder)
    ->add(new MapsService)
    ->add(…);
$result = $finder->find($houseNo, $postCode);

在内部,您将向LocalFinder发送$houseNo和$postCode。如果没有找到所需的数据,链中的下一个元素的任务是尝试找到所需数据。重复这一过程,直到到达链的末端或产生所需的数据。

这不是程序性/op/whatever的问题。

如果你能很容易地理解和维护代码,那就太好了。如果你能在6个月内完成,那就更好了。

你的功能块看起来很好——只要注意你的嵌套有多深。越浅越好。

我会尝试一些类似的方法:

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;
}

使用嵌套的try{} catch{}

你只有6个"if",这根本不算多,我过去处理的代码最多需要50个if,程序运行得很好。没有适合您当前问题的软件模式概念。DP不是一个特定问题的解决方案,它是一个反复出现的问题的概念。阅读模式有助于我个人学习更多解决社会问题的方法,包括编码模式、过程建模、配对编程中的社会问题等等,它提供了很多深思熟虑的想法。