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();
    }

    好吧,到此为止吧,手有点酸了,嗯嗯,,,,暂时先想到这些,以后再畅想。
  • 相关阅读:
    021.10 IO流 打印流
    1、Node.js 我的开始+安装
    021.9 IO流 流总结
    021.8 properties(开发使用频率高)
    021.7 装饰设计模式
    021.6 IO流 练习
    021.5 IO流——字符流
    scrapy基础知识之 CrawlSpiders爬取lagou招聘保存在mysql(分布式):
    scrapy基础知识之 关于爬虫部分一些建议:
    scrapy基础知识之 处理Redis里的数据:
  • 原文地址:https://www.cnblogs.com/Ivony/p/1570533.html
Copyright © 2011-2022 走看看