4

我与需要接收好几部影片,在特定网页上显示它们的应用程序的工作,目前这些视频也只能是来自YouTube,由于不允许其他供应商的实现,因为代码来获取视频数据作为预览图像直接放置在负责显示视频的View Helper中。这是一个很好的策略模式用例吗?

我想改变这个结构以便于添加新的提供者,比如Vimeo,并且我认为策略模式会是理想的,我会在我的View Helper中使用方法setVideoUrl(string $url),这个方法会调用方法getProviderStrategy(string $url)class VideoProviderFactory,这个工厂类会再返回,如果有的话,战略类,实现了interface VideoProvider,对于视频网址的提供者。

您认为如何?这是对的?我需要改变一些东西?

细节:我最初考虑将切换选择策略直接进入View Helper,但在看完这个问题后:I Strategy Pattern with no 'switch' statements?我看到我错了,于是class VideoProviderFactory出现了。

回答

5

这看起来像一个非常好的设计,有责任的适当分离。

为了给你一些更多的思考,考虑如何工厂将决定创建哪个策略。稍后当您想要添加另一个策略时,需要更改哪些内容?首先,你需要创建一个新的VideoProvider,那么你就必须改变出厂switch语句(如你所述),并包括对这个新战略的选择逻辑。现在,这在大多数情况下都是完美的,但如果您想在不改变工厂的情况下添加新策略呢?

的方法之一是具有与决定基于URL是否应该创建一个特定VideoProvider的方法的工厂一样的界面;让我们把它VideoProviderMatcher(伪代码):现在

interface VideoProviderMatcher { 
    bool understands(url) 
    VideoProvider create() 
} 

,该接口知道它是否能够理解的URL以及如何创建,涉及到它的VideoProvider。当您需要创建新战略时,您需要执行VideoProvider和相关VideoProviderMatcher。至于工厂,它改变封装的VideoProviderMatcher S和代表名单,以能理解给定URL的第一,使用链责任(伪代码):

class VideoProviderFactory { 
    List[VideoProviderMatcher] matchers 
    void registerMatcher(VideoProviderMatcher matcher) { 
    matchers.add(matcher) 
    } 
    VideoProvider getVideoProviderFor(url) { 
    foreach (matcher in matchers) { 
     if (matcher.understands(url)) return matcher.create() 
    } 
    } 
} 

现在唯一代码需要改变的是首先创建工厂的代码。理想情况下,它有一个VideoProviderMatcher的列表,它用于填充工厂,并且您只需将另一项添加到列表中。

现在,这值得吗?我认为这取决于匹配逻辑的复杂性,将视频提供者与URL匹配封装在一起的意愿,在添加新策略时保持工厂稳定的愿望,以及添加新策略的速度解决方案。

+0

好的。我唯一不明白的是为什么我们需要中间VideoProviderMatcher接口。无法将该功能作为VideoProvider类的一部分来实现吗? – hennes 2012-04-16 05:55:42

+0

@hennes国际海事组织,VideoProviderMatcher使URL的理解更加抽象。然后,匹配器可以接受实现,以基本上过滤出各种条件下的URL,例如url/url的一部分。 – Nrj 2012-04-16 06:22:27

+0

好的,这是一个很好的观点。感谢澄清。 – hennes 2012-04-16 06:39:21

相关问题