代码之家  ›  专栏  ›  技术社区  ›  Luke101

如何实施徽章?

  •  42
  • Luke101  · 技术社区  · 14 年前

    我已经考虑过实现徽章(就像堆栈溢出时的徽章一样),并且认为没有Windows服务是很困难的,但是如果可能的话,我想避免这种情况。

    我想出了一个计划来实施一些例子:

    • Audobiographer:检查配置文件中的所有字段是否都已填写。
    • 评论人:评论时,检查评论数量是否等于10,如果等于10,授予徽章。
    • 好答案:投票时,检查投票分数是25分还是更高。

    如何在数据库中实现这一点?或者另一种方法更好?

    4 回复  |  直到 14 年前
        1
  •  41
  •   Rex M    14 年前

    类似于stackoverflow的实现实际上比您所描述的要简单得多,它基于团队每隔一段时间丢弃的一些信息。

    在数据库中,只需存储 BadgeID - UserID 配对以跟踪谁拥有什么(以及一个计数或一个rowid以允许为某些徽章授予多个奖项)。

    在应用程序中,每个徽章类型都有一个worker对象。对象在缓存中,当缓存过期时,工作进程将运行自己的逻辑,以确定谁应该获得标记并进行更新,然后将自己重新插入缓存:

    public abstract class BadgeJob
    {
        protected BadgeJob()
        {
            //start cycling on initialization
            Insert();
        }
    
        //override to provide specific badge logic
        protected abstract void AwardBadges();
    
        //how long to wait between iterations
        protected abstract TimeSpan Interval { get; }
    
        private void Callback(string key, object value, CacheItemRemovedReason reason)
        {
            if (reason == CacheItemRemovedReason.Expired)
            {
                this.AwardBadges();
                this.Insert();
            }
        }
    
        private void Insert()
        {
            HttpRuntime.Cache.Add(this.GetType().ToString(),
                this,
                null,
                Cache.NoAbsoluteExpiration,
                this.Interval,
                CacheItemPriority.Normal,
                this.Callback);
        }
    }
    

    具体实施:

    public class CommenterBadge : BadgeJob
    {
        public CommenterBadge() : base() { }
    
        protected override void AwardBadges()
        {
            //select all users who have more than x comments 
            //and dont have the commenter badge
            //add badges
        }
    
        //run every 10 minutes
        protected override TimeSpan Interval
        {
            get { return new TimeSpan(0,10,0); }
        }
    }
    
        2
  •  4
  •   spinon    14 年前

    乔布斯。这就是关键。以设置的间隔运行的进程外作业,以检查您提到的条件。我认为您甚至不需要Windows服务,除非它需要一些外部资源来设置级别。我实际上认为stackoverflow也使用作业进行计算。

        3
  •  0
  •   Dustin Laine    14 年前

    您可以使用触发器并在更新或插入时进行检查,然后如果满足条件,则添加徽章。这样就不那么容易了。在3、2、1…

        4
  •  0
  •   griegs    14 年前

    注释必须存储在数据库中,对吗?我认为有两种主要的方法可以做到这一点。

    1)当用户登录时,您会得到一个注释计数。这显然不是所期望的方法,因为计数可能需要很多时间。

    2)当用户发布注释时,您可以进行计数,然后将计数与使用详细信息一起存储,也可以进行触发器,在添加注释时执行。然后,触发器将获取新创建的注释的详细信息,获取用户ID,获取一个计数,并将其存储在某种类型的表中。

    我喜欢触发器的概念,因为您的程序可以在不等待SQL Server完成其工作的情况下返回。