2010-04-27 50 views
0

要求的存储结果:接口设计问题:事务

  • 输入的多个源(社交媒体内容)到系统
  • 输出的多个目的地(社交媒体API的)
  • 源和目的地WILL加入

一些伪:

IContentProvider contentProvider = context.getBean("contentProvider"); 
List<Content> toPost = contentProvider.getContent(); 

for (Content c : toPost) { 
    SocialMediaPresence smPresence = socialMediaService.getSMPresenceBySomeId(c.getDestId()); 
    smPresence.hasTwitter(); smPresence.hasFacebook(); //just to show what this is 
    smPresence.postContent(c); //post content could fail for some SM platforms, but shoulnd't be lost forever 
} 

因此,现在我用尽了所有内容,我需要知道哪些内容已成功发布,并且如果它没有完全覆盖所有平台,或者未来添加了另一个平台,那么内容需要发布(因此,我的内容提供商不仅需要知道内容是否已经发布,而且还需要了解哪些平台)。我不在寻找代码,虽然sample/pseudo很好......我正在寻找一种解决这个问题的方法,我可以实现

+0

能否请你解释一下关于未来的平台好一点的一部分吗?假设我已经在Twitter上发布了46576条消息。您是否希望在我将其添加到我的帐户的那一刻,所有这些信息都会在GBuzz上传播?或者你的意思是你从加入GBuzz之后的第一条消息*开始向GBuzz发送一份拷贝? – 2010-04-27 13:27:35

+0

我希望所有5454635即可发布您添加帐户:)不会发生的那一刻,因为我会阻止它,并可能有一些例外这样的情况,但是从概念上你可以认为它像 – walnutmon 2010-04-27 13:41:35

回答

2

我会做这样的事情:

将消息(以其“原始”形式)存储在与其作者相关联的表或其他持久性结构中,并且具有时间戳(每个消息的创建日期/时间)。

创建关联作者/发布渠道。

创建一个(或可能更多)“未发送消息”的队列。此队列的基本结构是:

| channelId | MessageId | Status | Last Attempt Timestamp 

因此,假如我Pamar,和我订阅到Twitter,GBuzz和LinkedIn,当我在您的系统“后”这是我获得的主要信息表中的条目,并新的消息获取ID = 7686956 让我们假设该消息是在13时05分06秒的20100428

创建已经创造了它,共有3条记录在队列中添加后:

| channelId | MessageId | Status | Last Attempt Timestamp 
    | LinkedIn | 7686956 | New | 20100428 13:05:06 
    | Twitter | 7686956 | New | 20100428 13:05:06 
    | Gbuzz  | 7686956 | New | 20100428 13:05:06 

(注意,而我写的“LinkedIn”我希望有一个记录ID没有字符串)

现在,您将有一个进程从该队列获取记录(或者可能是每个通道的一个或多个进程,您选择如何扩展这个进程)访问队列,可能按照最老的尝试最新 - 这个“工作者”线程尝试在外部通道上发布,更新最后一次尝试时间戳,并设置状态(OK,失败)。 另一名工人可以在后台删除“OK”记录。

现在,当你添加“脸谱”我的频道列表中会发生什么?

简单,这种操作将有一个时间戳,太 - 你添加Facebook通道,我的用户的时刻。从上周

| channelId | MessageId | Status | Last Attempt Timestamp 
    | Facebook | 7685963 | New | 20100429 11:12:08 
    | Facebook | 7680064 | New | 20100429 11:12:08 
    | Facebook | 7697046 | New | 20100429 11:12:08 

当你为新频道“注入”这些信息,你可以决定的规则,例如,只有消息:您访问的消息表和转储这个时间戳在队列之前创建的所有消息,所以“节制”是隐含的。

添加一个全新的渠道,需要在结构上增加了几个记录,并开发一个工人或策略类连接到新的渠道和使用相关的登录配置文件和正确的API后出现。

+0

很大,这是我需要一个漂亮的解决方案,因为我也不是不知道他们要问我以后的事,这让我编写一个脚本,以便在必要时进行更改 – walnutmon 2010-04-27 14:51:07

0

为了保持它的灵活性 - 例如添加新目标 - 而不是将平台(twitter,facebook)整合到函数名称中,使其更通用。

smPresence.hasPlatform("facebook"); 

并迭代它所有的服务。在地图上保留发布成功标志,例如按服务编制索引。

这是你在找什么?

+0

即一个不好的决定。 – Bozho 2010-04-27 13:16:22

+0

他在这里有两个想法,你认为哪一个是一个糟糕的决定?为什么? – walnutmon 2010-04-27 13:21:41

+0

有该信息(排序)的硬编码字符串 – Bozho 2010-04-27 13:25:37

3
  1. 我认为没有什么可以让Content知道它将被分派到哪里。这个逻辑应该是外部的。
  2. 添加多个平台应该用Strategy pattern之类的东西来完成。如果你需要添加一个新的,你将不得不创建一个新的实现,并修改选择目标的服务来添加逻辑。
  3. 您可以使用依赖注入或单例而不是使用new运算符。 (我非常赞成的DI)

所以,像这样:

class Content { 
    String content; // or whatever type you store it in 
    ContentSource source; // who's the source of the content 
    // other relevant properties 
} 


interface SocialMedia { 
    boolean post(Content content); 
    boolean isContentSuitable(Content content); 
} 

class Facebook implements SocialMedia { 
    boolean post(Content content) { 
     // implement posting, return "true" if successful, "false" otherwise 
    } 

    boolean isContentSuitable(Content content) { 
    // decide whether this socialmedia is suitable for this content 
    // based on its source, its length or other features 
    } 
} 

class Twitter implements SocialMedia { .. similar to facebook } 


class ContentDestinationService { 
    List<SocialMedia> getContentDestinations(Content content) { 
     List<SocialMedia> result = new ArrayList<SocialMedia>(); 
     SocialMedia facebook = new Facebook(); 
     if (facebook.isContentSuitable(content)) { 
      result.add(facebook); 
     } 
     // etc for others 
     return result; 
    } 
} 

然后:

for (Content content : toPost) { 
    List<SocialMedia> destinations = 
      contentDestinationService.getContentDestinations(content); 

    int successfulPosts = 0; 
    for (SocialMedia sm : destinations) { 
     boolean success = sm.post(content); 
     // do something with this result, for example: 
     if (success) { 
      successfulPosts++; 
     } 
    } 
}