One of the first development rule is to write human readable
code
. Why ? To avoid to have to write comments ;-) Because it
will be read as a spoken language and it
separate important code from distracting one
.

What do you think about that line of code:

return DAL.FindAll(PublishedBy(Author));

Someone that has no clue about development might even read that code. Ok
except the DAL word ;-)

With C# 2.0 you are able to write readable code like this using Generics, and
the power of closures.
In C# 2.0 closure are supported through the form of anonymous delegates.

Check out the different methods returning collection accordign to predefined
rules: getAllUnpublished(), getAllPublished(),
getAllPublishedBy()… There are all using Predicate, so to say
anonymous delegate, that gives you human readable code.

Client code:

1 protected void Page_Load(object sender, EventArgs e)
2 {
3 GridView2.DataSource = TechHeadBrothers.Portal.BLL.ArticleBLL.getAllPublishedBy(“Laurent Kempé”);
4 GridView2.DataBind();
5
6 GridView3.DataSource = TechHeadBrothers.Portal.BLL.ArticleBLL.getAllWaitPublishingBy(“Laurent Kempé”);
7 GridView3.DataBind();
8 }

The Business Layer:

1 #region Using
2
3 using System;
4 using System.Collections.Generic;
5 using System.Text;
6 using TechHeadBrothers.Portal.Entities;
7 using TechHeadBrothers.Portal.DAL;
8
9 #endregion
10
11 namespace TechHeadBrothers.Portal.BLL
12 {
13 public static class ArticleBLL
14 {
15 static ArticleDAL DAL = new ArticleDAL();
16
17 public static List

getAll()
18 {
19 return DAL.GetAll();
20 }
21
22 public static List
getAllUnpublished()
23 {
24 return DAL.FindAll(NotPublished());
25 }
26
27 public static List
getAllPublished()
28 {
29 return DAL.FindAll(Published());
30 }
31
32 public static List
getAllPublishedBy(string Author)
33 {
34 return DAL.FindAll(PublishedBy(Author));
35 }
36
37 public static List
getAllWaitPublishingBy(string Author)
38 {
39 return DAL.FindAll(WaitPublishingBy(Author));
40 }
41
42 protected static Predicate
WaitPublishingBy(string author)
43 {
44 return delegate(Article a)
45 {
46 return !a.isPublished && (a.Author.ToLower() == author.ToLower());
47 };
48 }
49
50 protected static Predicate
PublishedBy(string author)
51 {
52 return delegate(Article a)
53 {
54 return a.isPublished && (a.Author.ToLower() == author.ToLower());
55 };
56 }
57
58 protected static Predicate
Published()
59 {
60 return delegate(Article a)
61 {
62 return a.isPublished;
63 };
64 }
65
66 protected static Predicate
NotPublished()
67 {
68 return delegate(Article a)
69 {
70 return (!a.isPublished);
71 };
72 }
73 }
74 }
75

The Entity class is represented as:

1 #region Using
2
3 using System;
4 using System.Collections.Generic;
5 using System.Text;
6
7 #endregion
8
9 namespace TechHeadBrothers.Portal.Entities
10 {
11 public class Article
12 {
13 private Guid uuid;
14
15 public Guid Uuid
16 {
17 get { return uuid; }
18 set { uuid = value; }
19 }
20
21 private string title;
22
23 public string Title
24 {
25 get { return title; }
26 set { title = value; }
27 }
28
29 private string description;
30
31 public string Description
32 {
33 get { return description; }
34 set { description = value; }
35 }
36
37 private bool ispublished;
38
39 public bool isPublished
40 {
41 get { return ispublished; }
42 set { ispublished = value; }
43 }
44
45 private string author;
46
47 public string Author
48 {
49 get { return author; }
50 set { author = value; }
51 }
52
53 public Article(Guid uuid, string title, string description, string author)
54 {
55 this.Uuid = uuid;
56 this.Title = title;
57 this.Description = description;
58 this.isPublished = false;
59 this.Author = author;
60 }
61
62 public Article(string uuid, string title, string description, string author)
63 : this(new Guid (uuid), title, description, author)
64 {
65
66 }
67
68 public Article(string title, string description, string author)
69 : this(Guid.NewGuid(), title, description, author)
70 {
71
72 }
73 }
74 }

And the Data Access Layer Article class:

1 #region Using
2
3 using System;
4 using System.Collections.Generic;
5 using System.Text;
6
7 #endregion
8
9 namespace TechHeadBrothers.Portal.DAL
10 {
11 interface IDataAccess
12 {
13 T Get(Guid uuid);
14
15 T Get(string uuid);
16
17 List GetAll();
18
19 List FindAll(Predicate match);
20 }
21
22 public class ArticleDAL : IDataAccess
23 {
24 List articles;
25
26 public ArticleDAL(List articles)
27 {
28 this.articles = articles;
29 }
30
31 public ArticleDAL()
32 {
33 this.articles = new List();
34
35 //TODO: Remove this is just for test
36 this.articles.Add(
37 new TechHeadBrothers.Portal.Entities.Article(“Les generics dans C#”,
38 “Démonstration de l’utilisation des générics dans C# 2.0”,
39 “Laurent Kempé”));
40
41 TechHeadBrothers.Portal.Entities.Article article =
42 new TechHeadBrothers.Portal.Entities.Article(“8BF7FEBE-9FEB-4db6-86B7-70A6C44B1CAA”,
43 “Les iterators dans C#”,
44 “Démonstration de l’utilisation des iterators dans C# 2.0”,
45 “Laurent Kempé”);
46 article.isPublished = true;
47 this.articles.Add(article);
48 }
49
50 #region IDataAccess

Members
51
52 public TechHeadBrothers.Portal.Entities.Article Get(Guid uuid)
53 {
54 for (int i = 0; i < articles.Count; i++)
55 {
56 if (articles[i].Uuid == uuid)
57 {
58 return articles[i];
59 }
60 }
61
62 return null;
63 }
64
65 public TechHeadBrothers.Portal.Entities.Article Get(string uuid)
66 {
67 return this.Get(new Guid(uuid));
68 }
69
70 public List GetAll()
71 {
72 return articles;
73 }
74
75 public List FindAll(Predicate match)
76 {
77 return articles.FindAll(match);
78 }
79
80 #endregion
81 }
82 }
83

[ Currently Playing : Sound Enforcer / Impact - Carl Cox (04:10)
]