Dennis’s Weblog

System Design

Posted on: March 26, 2009

Here are something that i learned from sample projects.(Blogengine.Net)

1.You should make full use of   Object Oriented Concept.

a.Provider Model.

When you design a core engine for blog, you should first design the core module. 

It will contain abstract class and interfaces which will help you to extend  and manage the functions later.

                           ProviderBase(it is a buildin class, that offer the function to commnicate with settings with web.config. that’s the benefit of extend

                                    ||          /*because of the extend, you can fully utilize ProviderBase class.  Use XML file the dynamic set the database provider without change your code.  After you add new functions

                                    ||           to BlogProvider, it will offer a model for later extend.  for example:  XMLProvider and DbBlogProvider, they are all ProviderBase object ! They have the same functions from 

                                   \/           ProviderBase.   */

                           BlogProvider

                                    ||             /* And when later use of these class(XMLProvider and DbBlogProvider) will be consider as BlogProvider; BlogProvider dbBlogProvider= new DbBlogProvider();

                                    ||                  This is a abstract process, It seems like there are a layer between DbBlogProvider and Database, when you change your database provider you didn’t need to change

                                    \/                 The code.*/

             (XMLProvider or DbBlogProvider)

                                    ||

                                    ||

                                    \/

                           BlogService  (use the data and functions provided by BlogProvider at the upper layer to offer the capability of retrieve and update data from database. As well as the basic logical.)

       private static void LoadProviders()

{

// Avoid claiming lock if providers are already loaded

if (_provider == null)

{

lock (_lock)

{

// Do this again to make sure _provider is still null

if (_provider == null)

{

// Get a reference to the <blogProvider> section

BlogProviderSection section = (BlogProviderSection)WebConfigurationManager.GetSection(“BlogEngine/blogProvider”);


// Load registered providers and point _provider

// to the default provider

_providers = new BlogProviderCollection();

ProvidersHelper.InstantiateProviders(section.Providers, _providers, typeof(BlogProvider));

_provider = _providers[section.DefaultProvider];


if (_provider == null)

throw new ProviderException(“Unable to load default BlogProvider”);

}

}

}

}

…………………………………Use these code to set different Provider for this BlogService(Offer basic function for operate on database)…………………………………

So from this , when you start a new project, you should think about how to utilize system buildin class and make use of them. Like language Localization and IHttpModule and so on.

b.Interface

public abstract class BusinessBase<TYPE, KEY> : IDataErrorInfo, INotifyPropertyChanged, IChangeTracking, IDisposable where TYPE : BusinessBase<TYPE, KEY>, new()

When you extend a interface you can not extend anything from it, you just want to make use of Object Oritented Concept ‘s  Polymorphism.  Implement the interface and then it can be pass into other function.    for example     

<httpHandlers>
<add verb=”*” path=”file.axd” type=”BlogEngine.Core.Web.HttpHandlers.FileHandler, BlogEngine.Core” validate=”false”/>
</httpHandlers>
How can this XML clause take effect ?
Becase :
 public class FileHandler : IHttpHandler
It extend the IHttpHandler, so it can be added to web.config file and take effect. Without the polymorphism concept, you can not implement this!
another example:
private static Uri GetPermaLink(IPublishable publishable)
And because of this, all the class that implement the IPublishable interface can put into this function and retrieve a Uri.
c. 还是继承!!!

public abstract class BusinessBase<TYPE, KEY> : IDataErrorInfo, INotifyPropertyChanged, IChangeTracking, IDisposable where TYPE : BusinessBase<TYPE, KEY>, new()
{
}
It will be extended by all the object used by this BlogEngine. And because of the extend, all the objects extend this class can make use of the function offered by it.
            <1>

public DateTime DateCreated
{
get
{
if (_DateCreated == DateTime.MinValue)
return _DateCreated;
return _DateCreated.AddHours(BlogSettings.Instance.Timezone);
}
set 
{
if (_DateCreated != value) MarkChanged(“DateCreated”);
_DateCreated = value; 
}
}

 

 

protected virtual void MarkChanged(string propertyName)

{

_IsChanged = true;

if (!_ChangedProperties.Contains(propertyName))

{

_ChangedProperties.Add(propertyName);

}

 

OnPropertyChanged(propertyName);

}

 

 

public event PropertyChangedEventHandler PropertyChanged;

/// <summary>

/// Raises the PropertyChanged event safely.

/// </summary>

protected virtual void OnPropertyChanged(string propertyName)

{

if (PropertyChanged != null)

{

PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

}

}

They are all in the BusinessBase class, Do you see anything ?

BusinessBase class extend the INotifyPropertyChanged interface:

 

    // Summary:

    //     Notifies clients that a property value has changed.

    public interface INotifyPropertyChanged

    {

        // Summary:

        //     Occurs when a property value changes.

        event PropertyChangedEventHandler PropertyChanged;

    }

It just contain a field of EventHandler,  and the client can set the EventHandler function to call When property are modified outside. MarkChanged function will call OnPropertyChanged to indirect call the eventHandler set by client.    And BusinessBase class implement this function for the descendants. When some field in BusinessBase changed it will call MarkChanged to indirect implement the eventHandler. That sounds very good, right ?

So this method is used to offer common method for descendants, very good!

<2> Leave the space for later reinforce

 

protected abstract void ValidationRules();//the descendant can implement this function and can be used by class outside.

 

/// <summary>

/// Gets whether the object is valid or not.

/// </summary>

public bool IsValid

{

get

{

ValidationRules();

return this._BrokenRules.Count == 0;

}

}

 

<3> use enum

 

virtual public SaveAction Save()

{

if (IsDeleted && !IsAuthenticated)

throw new System.Security.SecurityException(“You are not authorized to delete the object”);

 

if (!IsValid && !IsDeleted)

throw new InvalidOperationException(ValidationMessage);

 

if (IsDisposed && !IsDeleted)

throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, “You cannot save a disposed {0}”, this.GetType().Name));

 

if (IsChanged)

{

return Update();

}

 

return SaveAction.None;

}

<4> use bitwise operation to implement privileges!!

<5>for extend

#region Data access

 

/// <summary>

/// Retrieves the object from the data store and populates it.

/// </summary>

/// <param name=”id”>The unique identifier of the object.</param>

/// <returns>True if the object exists and is being populated successfully</returns>

protected abstract TYPE DataSelect(KEY id);

 

/// <summary>

/// Updates the object in its data store.

/// </summary>

protected abstract void DataUpdate();

 

/// <summary>

/// Inserts a new object to the data store.

/// </summary>

protected abstract void DataInsert();

 

/// <summary>

/// Deletes the object from the data store.

/// </summary>

protected abstract void DataDelete();

 

#endregion

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: