zoukankan      html  css  js  c++  java
  • SNS网站Design畅想曲(一)

    引子:
    新公司新项目,公司是一个营销广告公司,客户都是财大气粗的企业。而我们的任务就是让这些客户的网站看起来很有吸引力。

    最近Web 2.0的概念是最火的,所以我们的客户们都希望在自己的网站上有点儿Web 2.0的东东。那么Web 2.0里面什么最火呢?自然是类似开心网那样的SNS系统。设计一个SNS网站的框架,便是我在这个公司的主要工作。

    我希望这个畅想曲能成为一个系列文章。但恐怕我没有那么勤快。总的来说,我做过很多Design,却很少为Design写文章。因为Design的文章不好写,当然,会招来很多板砖也是原因之一。简单的说就是一个费力不讨好的活儿,所以我们也不要去嘲讽做权限的XXXX,或是做自然框架的YYYY。毕竟能把自己的Design拿出来Show,也是需要相当的勇气的。

    Design从来不是一个什么很玄妙的东西,就我看来,其实Design就是你栽了无数跟头后总结的经验,你多年养成的习惯,以及你的人生观、世界观等,这三者糅合在一起形成的本能反应。意即为:设计 = 经验 + 习惯 + 哲学。因为每一个人的习惯和对哲学的理解不同,所以做出来的Design也千差万别。或许不同的人的Design在一个大的面上会趋同,但总的来说,优秀的Design因为思想的不同,它们之间总是会有不同的地方。

    废话不多说,要不这篇文章就全成引子了。


    作为SNS系统,核心当然是用户。我为用户设计了两个类型:LoggedAccount和Member。简单的说LoggedAccount是当前登录的用户,在当前上下文(或者说HttpContext)中只存在一个,在整个网站上下文则存在多个。而Member,则是真正的用户实体。简单说来,LoggedAccount是Member的柄。一个LoggedAccount对象,代表着一个Member已经登陆。当Member登出后,LoggedAccount将不复存在,而Member永存。

    我为什么说设计思想是经验、习惯和哲学的叠加呢?将登录用户(LoggedAccount)与用户本质(Member)分开处理,这可以说是我栽了无数跟头后的总结,将登录用户命名为Account,则是习惯使然,至于将LoggedAccount视为Member的柄,而不是其延展。则恐怕又是哲学思想在作祟。经验在做多了设计后,会趋同。习惯在看多了设计范本后,也会趋同。所以优秀的设计到最后都会在大的面上趋同,细节上面却总是不尽相同。

    简单说来,LoggedAccount是这样一个类型:
    public class LoggedAccount : IIdentity
    {
      string Username { get; }
      //...
    }

    当需要获得Member对象时,只需要拿Username去检索就行了。

    譬如说我们可以有这样的类型和方法:
    public class MemberService
    {
      public Member GetMember( LoggedAccount account );
      //...
    }

    当然也可以:
    public class LoggedAccount
    {
      //...
      public Member Member{ get; }
    }

    顺便提一句,MemberService的方案,就很像是Model + Controller。

    当然,如果业务需要,我们可以继续抽象出Account类型,令LoggedAccount和GuestAccount为其派生类。分别代表已登录的用户和游客用户。我是敏捷的坚定拥护者,所以,设计尽可能简单,却不失扩展性,这就够了。

    继续我们的架构畅想,在SNS中,用户是核心,用户与用户之间的关系,则是核心中的核心。好友关系是最常见的,我为这个类型的命名是Friendship,既不是Member也不是Friend,而是FriendRelation。
    不过,像这种关系,恐怕一个典型的设计是这样的:
    public class User
    {
      //...
      public User[] GetFriends();
      //...
    }
    这种设计可以说是相当的糟糕,或者说这就是OOP与OOD的区别。这种代码,在OOP看来,这是完全符合当下的业务逻辑并且也能解决问题的。
    关于为什么设计成Friendship而不是别的,我不想多说,这会打断我畅想的思路。很多时候设计是一种条件反射,它并没有太多的道理可讲。糟糕的设计不一定就不能解决问题,华丽的设计也不一定就适用于你的场景。

    Friendship类型大体上像下面这样:

    public class Friendship : IRelationship
    {
      public Member Master{ get; }
      public Member Servant{ get; }
      //抱歉我暂时没有找到合适的单词。。。。
    }


    当然朋友关系作为核心逻辑,可以放到Member里面
    public class Member
    {
      //...
      public IEnumerable<Friendship> GetFriends();
    }

    好吧,到此为止吧,手有点酸了,嗯嗯,,,,暂时先想到这些,以后再畅想。
  • 相关阅读:
    PAT 甲级 1132 Cut Integer (20 分)
    AcWing 7.混合背包问题
    AcWing 9. 分组背包问题
    AcWing 5. 多重背包问题 II
    AcWing 3. 完全背包问题
    AcWing 4. 多重背包问题
    AcWing 2. 01背包问题
    AcWing 875. 快速幂
    AcWing 874. 筛法求欧拉函数
    AcWing 873. 欧拉函数
  • 原文地址:https://www.cnblogs.com/Ivony/p/1570533.html
Copyright © 2011-2022 走看看