与所有问题一样,设计可以让您的价值适应您没有比通常解决方案更快考虑的情况。
首先写一些解析来自一个提供者的数据 - 最简单的格式来处理数据。找到一种方法将该处理程序调整为您的爬虫。一定要封装建设 - 你应该总是这样做反正...
public class RoomTypeExtractor
{
private RoomTypeExtractor() { }
public static RoomTypeExtractor GetInstance()
{
return new RoomTypeExtractor();
}
public string GetRoomType(string content)
{
// BEHAVIOR #1
}
}
的GetInstance()
,ethod让你提升到一个战略模式的几乎免费。
然后添加你的第二个提供者类型。举个例子,比如,你有一个比第一种格式更普遍一些的稍微复杂的数据格式。通过重构什么是你的具体房型提取类与它背后的一个变化的抽象启动,并有GetInstance()
方法返回的具体类型的实例:
public abstract class RoomTypeExtractor
{
public static RoomTypeExtractor GetInstance()
{
return SimpleRoomTypeExtractor.GetInstance();
}
public abstract string GetRoomType(string content);
}
public final class SimpleRoomTypeExtractor extends RoomTypeExtractor
{
private SimpleRoomTypeExtractor() { }
public static SimpleRoomTypeExtractor GetInstance()
{
return new SimpleRoomTypeExtractor();
}
public string GetRoomType(string content)
{
// BEHAVIOR #1
}
}
创建一个实现了空对象模式的另一个变化。 ..
public class NullRoomTypeExtractor extends RoomTypeExtractor
{
private NullRoomTypeExtractor() { }
public static NullRoomTypeExtractor GetInstance()
{
return new NullRoomTypeExtractor();
}
public string GetRoomType(string content)
{
// whatever "no content" behavior you want... I chose returning null
return null;
}
}
添加一个基类,将使其更容易与责任链模式就是在这个问题上的工作:
public abstract class ChainLinkRoomTypeExtractor extends RoomTypeExtractor
{
private final RoomTypeExtractor next_;
protected ChainLinkRoomTypeExtractor(RoomTypeExtractor next)
{
next_ = next;
}
public final string GetRoomType(string content)
{
if (CanHandleContent(content))
{
return GetRoomTypeFromUnderstoodFormat(content);
}
else
{
return next_.GetRoomType(content);
}
}
protected abstract bool CanHandleContent(string content);
protected abstract string GetRoomTypeFromUnderstoodFormat(string content);
}
现在,重构原有的实施有加入一个基类成责任链管理
public final class SimpleRoomTypeExtractor extends ChainLinkRoomTypeExtractor
{
private SimpleRoomTypeExtractor(RoomTypeExtractor next)
{
super(next);
}
public static SimpleRoomTypeExtractor GetInstance(RoomTypeExtractor next)
{
return new SimpleRoomTypeExtractor(next);
}
protected string CanHandleContent(string content)
{
// return whether or not content contains the right format
}
protected string GetRoomTypeFromUnderstoodFormat(string content)
{
// BEHAVIOR #1
}
}
一定要更新RoomTypeExtractor.GetInstance()
:
public static RoomTypeExtractor GetInstance()
{
RoomTypeExtractor extractor = NullRoomTypeExtractor.GetInstance();
extractor = SimpleRoomTypeExtractor.GetInstance(extractor);
return extractor;
}
一旦这样做了,创建的责任链一个新的链接...
public final class MoreComplexRoomTypeExtractor extends ChainLinkRoomTypeExtractor
{
private MoreComplexRoomTypeExtractor(RoomTypeExtractor next)
{
super(next);
}
public static MoreComplexRoomTypeExtractor GetInstance(RoomTypeExtractor next)
{
return new MoreComplexRoomTypeExtractor(next);
}
protected string CanHandleContent(string content)
{
// Check for presence of format #2
}
protected string GetRoomTypeFromUnderstoodFormat(string content)
{
// BEHAVIOR #2
}
}
最后,添加新的链接链,如果这是一种较为常见的格式,你可能想给它更高的优先级,将其置于较高的链(支配链的顺序,真正的力量,当你做到这一点显而易见):
public static RoomTypeExtractor GetInstance()
{
RoomTypeExtractor extractor = NullRoomTypeExtractor.GetInstance();
extractor = SimpleRoomTypeExtractor.GetInstance(extractor);
extractor = MoreComplexRoomTypeExtractor.GetInstance(extractor);
return extractor;
}
随着时间的推移,你可能要添加的方式来动态如Cletus所指出的那样,为责任链增加新的链接这里的基本原理是Emergent Design。从高质量开始。保持高质量。开车测试。做这三样东西,你就可以用你的耳朵之间的模糊逻辑引擎克服几乎任何问题......
编辑
翻译成Java。希望我做对了;我有点生疏。
+1肯定 - (1)是要走的路(2)是死亡。 – 2010-03-24 01:02:54
嘿cletus,tnx for ur attention frist, 我也同意你的第一选择,但这是我在大学的最后一年的项目,他们问我一个通用的解决方案,因为你在选项2中提到。 我仍然是最后一年在此之前,研究生并没有遇到过这类问题。 你有任何经验的选项2. 任何方式tnx你的注意agin :) – 2010-03-24 09:19:25
@Kasun:这就是为什么人们离开大学时认为他们已经学会了如何编写软件,并破碎找出计算机科学和软件开发几乎都是无关紧要的。这将是一项艰巨的任务。在现实世界中,你可以更好地展示利用人类智能的成本远远低于创造机器智能。没有理由在学术界也不这样做。 – 2010-03-24 15:09:59