简读clubof网站源码之后的思考

news/2024/5/20 11:31:35/文章来源:https://blog.csdn.net/weixin_34281477/article/details/85422438
注:本文所阅读的clubof源码版本为FrienDevSourceCode_20081028,即2008年10月28日。

     按说昨天刚参加“微软技术创新日--北京站”活动之后, 今天就来评论其活动中产品的一些问题显
得不太厚道。但本文内容绝不应当看作是关于clubof的负面评论,并且可以说我是绝对支持这个网站
并响应其所“开放源码”这一举措的。甚至我还把该网站的宣传贴纸贴到了我的笔记本上。

     因为这是国内第一个开源并已上线动作的基于.net的SNS软件产品,更是先后有10名微软工程师
耗时三个月心血所开发出的产品。所以光就这一点来说,在国内的.net开发者中就应该会很有影响力,
甚至可能说是“从某种意义上传达出了微软内部开发者的一些声音”。

     报着这样的心态,我下载并开始阅读其源码,只不过是在阅读源码的过程中看到了一些有意思的
问题,其中还伴随着自己的一些思考。这里再次重申一下,就是我希望看到该产品发展的越来越好,
从而给国内的开发者竖立一个优秀的榜样。

    好了,下面就开始看一下我从源码中找出的一些问题。


   1.代码重复:
   
     位于FrienDevWeb项目下的"/Club/ActivityList.ascx"

     位于FrienDevWeb项目下的"/Club/ClubPostsList.ascx"

     重复代码段如下:
     
  
#region Protected Method
    
protected int GetQueryStringValue(string QueryName, int nullValue)
    {

        
if (string.IsNullOrEmpty(this.Page.Request.QueryString[QueryName]))
        {
            
return nullValue;
        }
        
return Convert.ToInt32(this.Page.Request.QueryString[QueryName]);
    }
    
protected string GetQueryStringValue(string QueryName, string nullValue)
    {

        
if (string.IsNullOrEmpty(this.Page.Request.QueryString[QueryName]))
        {
            
return nullValue;
        }
        
return this.Page.Request.QueryString[QueryName];
    }

    
protected bool GetQueryStringValue(string QueryName, bool nullValue)
    {
        
if (string.IsNullOrEmpty(this.Page.Request.QueryString[QueryName]))
        {
            
return nullValue;
        }
        
return Convert.ToBoolean(this.Page.Request.QueryString[QueryName]);
    }
    
#endregion
    
     建议:将这类代码重构到一个工具类当中,并以静态方法声明以方便调用。
     

   2.在ascx为后缀的cs文件中,存在类(实体)信息定义,比如:
   
     FrienDevWeb/Club/Activity/FeedBackSummary.ascx.cs
     
    
class CustomQuestionAnswers
{
    
public string UserHomeUrl { getset; }
    
public string Name { getset; }
    
public string Answer { getset; }
    
public string Question { getset; }
}

   
    建议:可以新创建一个文件夹甚至项目来统一管理这种类实体信息。
    

   3. 业务逻辑被放置到了页面Page_Load之中,比如:
   
   FrienDevWeb/Club/Activity/FeedBackSummary.ascx.cs:


protected void Page_Load(object sender, EventArgs e)
{
    
string activityIdString = Request["activityId"];
    
if (!int.TryParse(activityIdString, out m_activityId))
        Response.Redirect(
"~/Home/Default.aspx");
    
if (!ActivityRules.Instance.IsCurrentUserIsActivityPromoter(m_activityId))
        Response.Redirect(
"~/Home/Default.aspx");

    
//下面是业务逻辑代码
    IEnumerable<User> users = ActivityRules.Instance.GetActivityJoined(m_activityId, -1);
    List
<string> userIds = new List<string>();
    
foreach (User user in users)
    {
        userIds.Add(user.UserId);
    }
    List
<int[]> marks = ActivityRules.Instance.GetUsersFeedBackMark(m_activityId, userIds);
    
int markCount = marks.Count != 0 ? marks.Count : 1;
    
int overallSum = 0;
    
int contentSum = 0;
    
int organizeSum = 0;
    
foreach (int[] mark in marks)
    {
        overallSum 
+= mark[0];
        contentSum 
+= mark[1];
        organizeSum 
+= mark[2];
    }
    
//业务逻辑代码结束
    lblOverallMark.Text = overallSum.ToString();
    lblContentMark.Text 
= contentSum.ToString();
    lblOrganizeMark.Text 
= organizeSum.ToString();
    lblOverallAverage.Text 
= (overallSum / markCount).ToString();
    lblContentAverage.Text 
= (contentSum / markCount).ToString();
    lblOrganizeAverage.Text 
= (organizeSum / markCount).ToString();
   
}

    
    上面代码段中的“IEnumerable<User> users = ActivityRules.Instance...” 开始,到foreach循环结束,
我感觉这块代码应该被放在业务逻辑层中,而Page_Load方法要做的事就是获取表单数据和相应控件的信息绑定
即可,如果像这样把业务逻辑代码强加到当前方法后,会造成当前page_load的(业务)流程代码过多,造成代码阅
读的困难。

       
   4. 方法定义后却未被使用,怀疑是“代码拷贝”的恶果,参见:ClubInviteService.cs中有对上面的
GetQueryStringValue等私有方法的声明。


   5. WebService中的实体类声明倒底该不该放到相应的服务类定义中,我想这个问题大家可能会有不同意见,
但我的想法是提出来放到一个公共的entity或信息类项目中,这样会更清楚,不是吗?

    出现这个情况的是FrienDevWeb/App_Code/SelectFriendsService.cs,代码如下:

//注:代码上方为SelectFriendsService类的定义
public class UserItem
{
    
public UserItem()
    { }

    
public UserItem(string UserId, string FullName, string PhotoFileName)
    {
        
this.UserId = UserId;
        
this.FullName = FullName;
        
this.PhotoFileName = PhotoFileName;
    }

    
private string m_UserId;
    
public string UserId
    {
        ..
    }

    
private string m_FullName;
    
public string FullName
    {
       ..
    }

    
private string m_PhotoFileName;
    
public string PhotoFileName
    {
        ..
    }
}



    当然这几个小问题不会影响系统的稳定性或性能,只不过是造成代码阅读和项目分布理解上的困扰。

    下面就到了我所认为的分层问题了,其实看过MVCStore_Preview1A源码的人可能会发现一些情况,
就是其对Service的引入和使用,这些Service是封装的是业务逻辑,这类逻辑的数据访问代码并不是直
接访问LINQ设计器所生成的类或方法,而是又封装了一层,而这一层的封装有统一的命名规范,即添加
后缀“Repository”,这类做的好处应该是将频繁使用的数据访问方法先抽出来加以封装,比如说订单
等,而Service层会对这类频繁访问的代码直接使用,以确保Service只加关心业务逻辑层的实现,我想
MVCStore的做法是可以认真考虑并加以参考的。比如说:

/// 位于MVCStore_Preview1A代码的SqlOrderRepository.cs中
/// <summary>
/// Returns a current, unchecked-out order for the current user
/// </summary>
public Order GetCurrentOrder(string userName)
{
    Order result
= _orderRepository.GetOrders().CurrentOrderForUser(userName).SingleOrDefault();

    
if(result==null)
    {
        
//create a new one
        result=new Order(userName);
        
    }
    
return result;
    
}

//Commerce.Data.SqlCatalogRepository
public IQueryable<Order> GetOrders() {

    var orders 
= from o in _db.Orders
                 let items 
= GetOrderItems(o.OrderID)
                 let transactions 
= GetTransactions(o.OrderID)
                 select 
new Order
                            {
                                Status 
= (OrderStatus)o.OrderStatusID,
                                DateCreated 
= o.CreatedOn,
                                ID 
= o.OrderID,
                                OrderNumber 
= o.OrderNumber,
                                Items 
= new LazyList<OrderItem>(items),
                                Transactions 
= new LazyList<Transaction>(transactions),
                                ShippingAddress 
= GetAddresses().Where(x => x.ID == o.ShippingAddressID).SingleOrDefault(),
                                BillingAddress 
= GetAddresses().Where(x => x.ID == o.BillingAddressID).SingleOrDefault(),
                                ShippingMethod 
=GetOrderShippingMethod(o.ShippingMethod, o),
                                UserName 
= o.UserName,
                                UserLanguageCode
=o.UserLanguageCode,
                                DateShipped
=o.DateShipped,
                                EstimatedDelivery 
= o.EstimatedDelivery,
                                TrackingNumber
=o.TrackingNumber,
                                TaxAmount
=o.TaxAmount,
                                DiscountReason
=o.DiscountReason,
                                DiscountAmount
=o.DiscountAmount
                                
                            };
    
return orders;

}

///该方法被放在了Commerce.Data.OrderFilters中,但我感觉这块代码应与上面代码放在一起
public  static IQueryable<Order> CurrentOrderForUser(this IQueryable<Order> qry, string userName)
{
     
return from o in qry
            
where o.UserName == userName && o.Status==OrderStatus.NotCheckoutOut
            select o;
   
}

     当然MVCStore这种数据获取方式有个问题,就是效率,即_orderRepository.GetOrders()先是返回所有定单,
而不是仅获取符合条件的数据,并且在后续方法中访问CurrentOrderForUser方法来传入条件 。

     注:当然这个判断可能会有误差,就是LINQ中如果不使用tolist这类方法时,查询是不会被马上执行的,这个技
术好像叫lazyload,如果上面两个方法(GetOrders方法和CurrentOrderForUser方法)的调用只是在将linq语法转
(翻)译成sql语法的话,上面的观点就不成立了,因为在Service中代码的最后会调用SingleOrDefault(),如下


    _orderRepository.GetOrders().CurrentOrderForUser(userName).SingleOrDefault();

    也就是在该方法(SingleOrDefault)调用时,才会真正将转义过来的sql语句加以执行(向数据库递交查询请求)。
    
    当然这也是个猜测,如果有对LINQ研究的比较深入的朋友可以测试一下,然后告之一下我,以免我的判断出
现误差,在此先行道谢了。


    下面再看看在业务规则层中的一个小问题:)

    有关于单体(singleton)模式的实现方法,我看到了这样的代码(位于FriendRules):


    
public static FriendRules Instance = new FriendRules();

    
private FrienDevDataContext m_DataContext = FrienDevDataContext.Instance;

    
private FriendRules()
    {
    }
..



    然而在UserRules.cs文件中又出现了下面这种单体模式的“经典实现”代码:   
   
    private static UserRules _instance;

    
public static UserRules Instance
    {
        
get
        {
            
if (_instance == null)
            {
                _instance 
= new UserRules();
            }
            
return _instance;
        }
    }


    看来在如何实现单体模式上,团队的开发者中还是有不同意见和编写方式的:)
    
    不过如果使用下面这种方式的话,可以说会造成一个并发访问的问题,而这个问题以前在网上就有
人提出过并给出了一个方案,这里就不再多说了。

    建议将上面的UserRules代码修改成:
    
   
    public static UserRules Instance
    {
        
get
        {
            
if (_instance == null)
            {
                
lock (lockHelper)
                {
                    
if (_instance == null)
                    {
                        _instance 
= new UserRules();
                    }
                }
            }
            
return _instance;
        }
    }
    
    好了,限于尚处于刚开始阅读clubof代码,对该项目的代码还远远谈不上了解,今天的内容就先到这里了。
    

    最后希望国内.net开发的所有软件产品越做越好,市场越来越大。

 

     原文链接:http://www.cnblogs.com/daizhj/archive/2009/03/04/1402708.html

     作者: daizhj, 代震军

     Tags: clubof,source code, 源代码

     网址: http://daizhj.cnblogs.com/

   

   

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_825826.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

推荐一款niubility的网站技术分析插件

Wappalyzer是一款功能强大的、且非常实用的网站技术分析插件&#xff0c;通过该插件能够分析目标网站所采用的平台构架、网站环境、服务器配置环境、JavaScript框架、编程语言等参数。 Wappalyzer使用方法 1、安装插件 Wappalyzer支持chrome、firefox浏览器。用户可以在官网…

分享10个ico图标搜索下载网站

为大家提供10个icon搜索下载的网站&#xff0c;这些图标都有明确的分类&#xff0c;你可以从中选出很多精美的图标哦。 1. IconsPedia IconsPedia是一个搜索下载png图片的地方&#xff0c;里面含有海量的图标&#xff01; 2. veryico 超过1000组的20000高质量的web图标。每个图…

css教程–十步学会用css建站(全)

本教程主要参考Creating a CSS Layout from scratch&#xff0c;由Jorux翻译&#xff0c;以意译为主&#xff0c;其间加入了不少Jorux的个人观点&#xff0c;省略了一些多余的说明&#xff0c;请读者明鉴。 目录&#xff1a; 第一步&#xff1a;规划网站&#xff0c;本教程…

[转]雅虎-网站性能优化的34条黄金法则

2019独角兽企业重金招聘Python工程师标准>>> 1、尽量减少HTTP请求次数 终端用户响应的时间中&#xff0c;有80%用于下载各项内容。这部分时间包括下载页面中的图像、样式表、脚本、Flash等。通过减少页面中的元素可以减少HTTP请求的次数。这是提高网页速度的关键步骤…

网站高数据量访问下数据库瓶颈解决方案

数据库一向是网站架构中最具挑战性的&#xff0c;瓶颈通常出现在这里。又拍网的照片数据量很大&#xff0c;数据库也几度出现严重的压力问题。 因此&#xff0c;这里我主要介绍一下又拍网在分库设计这方面的一些尝试。 又拍网是一个照片分享社区&#xff0c;从2005年6月至今积累…

网站安全狗V3.1版 新增数据包外发拦截功能

2019独角兽企业重金招聘Python工程师标准>>> 网站安全狗是一款集WebShell病毒查杀和WAF为一体的网站安全防护软件&#xff0c;采用基于WEB容器插件式的技术来实现安全防护。涵盖了网马/木马扫描、防SQL注入、防xss注入、防盗链、防CC攻击、网站流量实时监控、网站CP…

酷站欣赏:12个漂亮的国外单页网站设计案例

单页网站把所有的内容都展示在一个页面中&#xff0c;让访客访问页面的时候不需要跳转到其它的页面。网站的内容不是很多而且将来内容也不怎么增加的情况下&#xff0c;制作成单页网站&#xff08;Single Page Websites&#xff09;的形式是很好的选择。 网站导航是单页网站的关…

在 Windows Azure 网站 (WAWS) 上对 Orchard CMS 使用 Azure 缓存

编辑人员注释&#xff1a; 本文章由 Windows Azure 网站团队的项目经理 Sunitha Muthukrishna 撰写。 如果您当前的 OrchardCMS 网站在 Windows Azure 网站上运行多个实例&#xff0c;如果不使用某种形式的分布式缓存&#xff0c;您的服务器场中的多个不同节点之间的缓存将会失…

手把手搭建web网站

就拿我自己来说,我为什么学习Linux呢? 大学时候有一次公开课,誉天邹sir讲Linux,他几分钟时间搭建好了一个网站,我作为一个小白,无比震惊,真的太神奇了! 有没有可能以后的某一天,自己也能独立搭建web网站,并且能为访问? 网上也有很多搭建web网站教学,看了很多,,百度一找,然后按…

域名 主机头 同一个IP在IIS环境下架设多个网站

域名 主机头 同一个IP在IIS环境下架设多个网站由于各种原因&#xff0c;我们有时候需要在一个IP地址上建立多个web站点&#xff0c;在IIS5中&#xff0c;我们可能通过简单的设置达到这个目标。在IIS中&#xff0c;每个 Web 站点都具有唯一的、由三个部分组成的标识&#xff0c;…

8月国内网站流量统计TOP5:360安全中心季军

IDC评述网&#xff08;idcps.com&#xff09;09月01日报道&#xff1a;根据中国互联网协会-中国网站排名公布的最新数据显示&#xff0c;截至2015年8月30日&#xff0c;国内网站独立访问量五强分别是百度、腾讯网、360安全中心、淘宝网、搜狗。具体情况见下图&#xff1a;通过上…

Hadoop学习笔记—20.网站日志分析项目案例(一)项目介绍

2019独角兽企业重金招聘Python工程师标准>>> 一、项目背景与数据情况 1.1 项目来源 本次要实践的数据日志来源于国内某技术学习论坛&#xff0c;该论坛由某培训机构主办&#xff0c;汇聚了众多技术学习者&#xff0c;每天都有人发帖、回帖&#xff0c;如图1所示。 图…

在线小说网站的设计与实现(附源码)

版权声明&#xff1a;欢迎转载&#xff0c;请注明出处 最近在做一个课程设计&#xff0c;在线小说网站的设计&#xff0c;以下是课题要求&#xff0c;需要项目练手的童鞋可以试试身手。 由于最近新学了JavaEE&#xff0c;所以采用了jspservlet来写&#xff0c;前端部分用了少量…

Java开发牛人十大必备网站

质量是衡量一个网站的关键因素&#xff0c;我个人认为这些网站质量都很好。接下来&#xff0c;我会跟大家分享我是如何使用这些网站学习和娱乐的。或许你会认为有些网站适合任何水平的开发者&#xff0c;但是我认为&#xff1a;对于Java开发牛人来说&#xff0c;网站的好坏取决…

由12306.cn谈谈网站性能技术

12306.cn网站挂了&#xff0c;被全国人民骂了。我这两天也在思考这个事&#xff0c;我想以这个事来粗略地和大家讨论一下网站性能的问题。因为仓促&#xff0c;而且完全基于本人有限的经验和了解&#xff0c;所以&#xff0c;如果有什么问题还请大家一起讨论和指正。&#xff0…

自己整理的android学习网站~持续更新

安卓100&#xff0c;分类比较详细&#xff0c;可以作为熟悉基础知识后&#xff0c;练习使用。 http://www.android100.org/html/c3/安卓开发手册&#xff0c; 类似上面网址的分类&#xff0c;也是比较清晰 http://www.jdzhao.com/basic/这个网站特别好&#xff0c;就是androi…

人工智能和机器人网站、图像处理网络资源

人工智能和机器人网站、图像处理网络资源 (2007-08-24 12:07:30) 标签&#xff1a; 校园生活 分类&#xff1a; 工作篇 ITHao123.COM&#xff0c;邮箱&#xff1a;ithao123163.com 第一部分&#xff1a;人工智能网站 科大人工智能实验室 网址&#xff1a;http://ailab.ai.ustc…

j2ee 简单网站搭建:(六)使用 hibernate validation 实现 domain 层实体类验证

为什么80%的码农都做不了架构师&#xff1f;>>> 《j2ee 简单网站搭建&#xff1a;&#xff08;一&#xff09; windows 操作系统下使用 eclipse 建立 maven web 项目》《j2ee 简单网站搭建&#xff1a;&#xff08;二&#xff09;添加和配置 spring spring-mvc 的…

云服务器 管理控制台_如何将自己的网站上线到服务器端详解!

一个好网站首先要有一个好的域名&#xff0c;我们常见的网站后缀一般都是.com和.cn的较多。本章来谈一下如何将自己的网站上线到服务器端&#xff0c;这样的话就不必受限与本地局域网了&#xff0c;在任何有网络的地方都可以进行访问了。|首先我们要了解.com是国际域名后缀&…

网站爆库php,[原创]WEB安全第四章SQL注入篇05 mysql+php 手工注入篇 爆库 爆表 爆字段...

[原创]WEB安全第四章SQL注入篇05 mysqlphp 手工注入篇 爆库 爆表 爆字段在上面一章mysqlphp手工注入篇 在最后用到的一个函数 group_concat()可以将查询的字段的数据查询出来可以用利这个函数 将mysql所有的库名查询出来1、查询所有的库http://target_sys.com/article.php?id…