1

我正在将我创建的几个应用程序(刮板)重构为一个应用程序。有一些刮板,如TwitterScraper,FacebookScraper等。名称只是为了更好地解释问题。

假设我想使用这些刮板检索人。我们可以在每个爬虫中使用不同的方式进行搜索。例如,在 Facebook 中,我们可以按姓名、年龄等搜索……或者简单地获取某个特定组中的所有用户,这意味着我们有两种搜索方式。Twitter和其他人也会发生同样的情况......

我考虑过以下设计:

public interface IScraper {
    IEnumerable<User> Search(IParameter parameters);
}

然后有:

public class FacebookGroupsScraper : IScraper {
    public IEnumerable<User> Search(IParameter parameters) {
        //... search here using the group url, etc.
    }
}

public class FacebookOtherScraper : IScraper {
    public IEnumerable<User> Search(IParameter parameters) {
        //... search here using the name, age, country, or whatever...
    }
}

但我肯定违反了Liskov Substitution Principle,因为我必须在每种方法中做这样的事情:

public class FacebookOtherScraper : IScraper {
    public IEnumerable<User> Search(IParameter parameters) {
        var p = parameters as FacebookOtherParameter;

        //We can only work here with the expected parameters 
        //(FacebookOtherParameter class in this case)
    }
}

设计它的好方法是什么?

4

2 回答 2

0

看起来实现之间的区别在于它们采用的参数类型。

因此,为了遵守 LSP,我认为最好将接口更改为具有单独的方法或具有单独的接口,每个接口都有不同的方法,采用不同类型的参数:

//... search here using the group url, etc.
public interface GroupScrapper{
     IEnumerable<User> SearchByGroup(IGroupParameter parameters...);

}
 //... search here using the name, age, country, or whatever...
public interface UserInfoScrapper{
     IEnumerable<User> SearchByInfo(IInfoParameter parameters...);

}

或作为单个接口:

public interface IScraper {
    IEnumerable<User> SearchByGroup(IGroupParameter parameters...);

    IEnumerable<User> SearchByInfo(IInfoParameter parameters...);
}

这样,每个实现都将满足其中一种方法的约定。

这种方法的问题是你必须有一个非常静态的参数集,并且提前完全知道。如果您必须不断添加新类型的参数,那么方法和/或接口的数量将会激增。

于 2013-09-17T23:26:25.970 回答
0

我通常为这种情况做通用的。(请注意下面的代码可能无法编译)

public interface IScraper<T> where T : IParameter
{
    IEnumerable<User> Search(T parameters);
}

public class FacebookParameter : IParameter{
    public string GroupUrl{ get; set; }
}

public class FacebookGroupsScraper : IScraper<FacebookParameter> {
    public IEnumerable<User> Search(FacebookParameter parameters) {
        //... search here using the group url, etc.
    }
}

但是我忘记了如何在消费者级别使用它。

于 2013-09-18T01:25:24.233 回答