65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP.NET 1.1 可扩展主页框架:模式导向设计

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.90/5 (88投票s)

2004年7月1日

9分钟阅读

viewsIcon

362962

downloadIcon

6500

使用 ASP.NET 和 C# 开发主页框架。

Sample Image - MasterPage.jpg

引言

本文旨在详细阐述框架开发过程中涉及的流程,并以一个使用 ASP.NET 和 C# 开发的“主页框架”为例。本文将向您解释使用 UML 的面向对象设计方法、框架中涉及的设计模式,以及一些模式导向架构与设计 (POAD) 的知识,可谓包罗万象。

主页框架开发

在面向对象软件工程中,一切都始于用例。在开发 Web 应用程序时,其中一个用例是“用户需要一个始终如一的外观和感觉”

image002.jpg

这有什么大不了的?我们每天到处都能看到一致的网站,等等等等……我们看到漂亮的“性感”网站,但我们没有看到一件事(好吧!你看不见),如果整个网站需要一个更改,维护成本会是多少。现在看起来很麻烦了 :)

除了用于一致性的一些 CSS 样式表,我们还需要什么?一个框架,一个主页框架,它应该可扩展、易于使用、可插拔且可进行视觉修改!(听起来很棒!多么美好的愿望 :D)ASP.NET 中目前不存在这样的东西(Whidbey 中有一个,但还有很长的路要走)。

我开始在网上搜索,找到了一些有趣的文章

这些文章是非常好的起点,所以我从它们中汲取了所有宝贵的建议并进一步深入,因为我正在寻找一种可重用/可扩展的框架。我承担了重新设计从未存在过的整个轮子的责任,这怎么样 ;)。

我所采取的方法,我所设计的是模式导向架构和设计 (POAD),而不是设计模式,它们是不同的。我称之为 POAD,因为我的应用程序具有一种独特的“外观和感觉”,它遵循一种模式。POAD 意味着您拥有整个原型模式,您的应用程序将遵循该模式,但稍后会被具体结构所覆盖(这个概念需要一整篇文章,我稍后会写,并附带一些示例,希望在下个月)。所以主页有页眉、页脚、导航器、菜单/子菜单和内容占位符,这些占位符将根据具体页面的需要稍后填充,怎么样,听起来不错。让我们进一步!以下是设计基于 POAD 的软件所涉及的步骤。

  • 绘制您的框架将提供的整个抽象模式。
  • 找出负责完成工作的对象。
  • 找出它们之间的关系。
  • 找出所需的设计模式。
  • 在设计对象时,详细阐述它们,并找出它们的功能。
  • 编写测试用例。

sdl.img

涉及的步骤

绘制您的框架将提供的整个抽象模式。

这是我们框架的原型模式

image001.png

图 1(主页布局/模式)

主 Web 用户控件

如果我们把这个模式分解成对象,很明显我们应该有一些骨架或模板作为占位符,也就是说,应该有一个主页,它由占位符组成,比如页眉、页脚、徽标、菜单、导航器和内容等等。

image003.png

由于我们的计划是可视化地改变这些占位符,我们可以安全地将这些占位符放入一个用户控件(`PageUserControlBase`)中,该控件又包含所有占位符。称之为 Master 用户控件,您可以在其中定义这些内容的布局。现在,我们的模型将有一个 Master Page,它又由 Master User-Control(`PageUserControlBase`)组成,而 Master User-Control 又由占位符组成,就像这样

image005.png

越来越近了,太棒了!:) 现在决定通过用户控件等提供可视化部分。我们希望这个用户控件在运行时可插拔,所以我们将使用 web.config 在运行时动态加载它,像这样

<appSettings>
   <add key="MasterPageUserControl" value="MasterPageUserControl.ascx"/>
</appSettings>

我们的框架将 Master User-Control (`PageUserControlBase`) 类的所有功能封装在一个程序集中,作为基类/抽象类,以便我们将来需要时可以对其进行扩展。它看起来是这样的

image007.png

通过这种方法,如果将来我们决定采用其他外观和感觉的母版用户控件,我们所需要做的就是扩展 `PageUserControlBase` 类并使用它

image009.png

<%@ Control Inherits="Shams.Web.UI.MasterPages.PageUserControl" %>

或者这样使用它

<%@ Control Inherits="Shams.Web.UI.MasterPages.PageUserControlExtra" %>

`PageUserControl` 或 `PageUserControlExtra` 将为我们提供对 `WebControls.PlaceHolder`(s) 的访问。以下是 `PageUserControlBase.ascx` 的样子:

image011.png

image012.png

这很简单,对吧?是的,它就是这样。现在可视化组件可以很容易地扩展,并且可以通过 `web.config` 进行插拔,并且已经准备好了。所以在设计框架时,我们目标明确,这是一个可扩展和可插拔的框架,太棒了 :)。还需要什么呢?嗯,还有很多工作要做。到目前为止,我们所做的一切都是通过可插拔的 Master User Control-Base 提供了一致的外观和感觉。我们还有很长的路要走。让我们首先分析一下 HTML/aspx 页面是什么样子的

image013.png

你可以看到页面本身有四个部分,让我们仔细检查它们

  • A 部分:- HTML 头部,描述代码隐藏语言、页面标题、元信息和 HTML 正文等。
  • B 部分:- 表单区域。
  • C 部分:- 主用户控件区域,[或任何控件]。
  • D 部分:- HTML 页脚区域。

主自定义控件

每个页面只能有一个 HTML 表单。我们将所有服务器控件放在此表单中(C 部分)。因此,我们需要另一个对象来封装上述所有 HTML 渲染内容,例如 A 部分、B 部分、C 部分和 D 部分。如果您查看 `Control` 类,它具有我们正在寻找的所有功能。`Control` 是一个复合控件,这意味着我们可以在其中放置其他控件。因此,通过扩展 `Control` 对象来开始使用自定义控件是一个很好的起点。这个扩展的自定义控件,我们称之为 `PageControlBase`,将提供 HTML 渲染功能,并且它将包含一个 `System.Web.UI.HtmlControls.HtmlForm` 对象。这个 Form 对象将用于添加我们著名的主用户控件或 C 部分。现在,我们的主页面将由一些主自定义控件和主用户控件组成。这是展示所有这些的 UML 图

image015.png

现在我们有了一个可插拔的主用户控件,还需要一个自定义控件来创建所有 HTML 部分。

我们需要一个集成器类,它将主用户控件插入自定义控件表单并将其附加到主页。这就是派生自 `UI.Page` 类的 `MasterPageBase` 类:-

image017.png

主页框架中使用的设计模式

当您计划任何基于原型或遵循 POAD 的框架时,最有效的模式是模板设计模式。以下是演示此模式的代码

public interface IPageControl
      {
            System.Web.UI.Control ParentControl();
 
            void HtmlRenderStarts();
            void PreHtmlRender();
            void HtmlRender();
            void PostHtmlRender();
            void HtmlRenderEnds();
 
            /// <summary>

            /// The title page can be set with this property

            /// </summary>

            string PageTitle
            {
                  get; 
                  set;
            }
            /// <summary>

            /// </summary>

            string MetaInfo
            {
                  get; 
                  set;
            }
      }

我们定义了执行序列/模式,该模式稍后将被派生类覆盖。

模板设计模式在两种情况下使用

  • 在自定义控件中定义的模板:-

    image019.png

  • 这是使用相同设计模式的另一个地方

    image021.png

使用的其他模式是工厂模式和复合设计模式。工厂模式用于创建类,并且应该提供一个位置;如果计划在它们的创建周围放置一些业务逻辑,我们可以在不破坏现有代码的情况下完成它。

复合模式内置于 .NET 框架中,例如 `Control` 类本身就是基于复合模式的。复合模式的简单形式是一个对象列表的列表。我没有重新发明自己的对象容器,而是将 `Control` 类作为我的起点。

image004.jpg

就这样,我们完成了框架。你所需要做的就是让你的页面继承自 `MasterPage` 类,并重写你希望在具体类中改变的内容。我们如何做到这一点,在下面的 UML 图中显示了

image023.png

让我们讨论一下在实现过程中会遇到的一些典型场景

1. 创建主页骨架:-

如前所述,我们只需要从 `MasterPageBase` 派生。以下是代码片段作为示例

image025.png

这是我们将得到的结果;这是一个主页骨架。

MasterPage.jpg

视觉设置来自 `web.config`,即

<appSettings>
  <add key="MasterPageUserControl" value="MasterPageUserControl.ascx"/>
</appSettings>

如果你的 `MasterPage` 有其他布局,你可以创建自己的用户控件并修改 `web.config` 中的签名。

以下是上述场景不太详细的对象序列图:-

sequence.png

2. 从主页骨架创建主页:-

我们将从 `MasterPageBase` 创建一个 `MasterPage` 类,并用我们自己的 `UserControl`s 覆盖占位符。以下是此示例代码片段:-

image029.png

这是我为我的示例网站创建的主页面

imageJujju031.jpg

3. 从您刚刚创建的主页创建自己的页面。

您所需要做的就是将这个 `MasterPage` 类作为所有页面的基类,并覆盖您可能想要不同的功能,并使内容保持一致:-

image033.png

以下是网站其余页面的建议 UML 图:-

image035.png

4. 如果您有多个主页(MDI 场景)

在此特定场景中,您将重写 `LoadPageUserControl()` 函数,其中框架会动态加载用户指定的主控件。以下是此场景的代码片段:-

image037.png

这是表示此场景的 UML 图:-

image039.png

以下是通用情况的 UML 表示,MDI(多文档界面)或 Web 应用程序中的多主界面(MMI):-

image040.jpg

好了,暂时就这些了,希望您和我一起享受了这次 MMI 之旅,虽然旅途有点颠簸,但我们很高兴安全地回到了家(页面)。现在享受这个框架吧,您只需包含程序集 `Shams.Web.UI.MasterPages.dll` 即可开始使用它。我还提供了一个示例,可以帮助您设计应用程序。请将您的反馈发送给我,以便进一步改进框架,谢谢。

结论

软件架构围绕结构展开,框架为其提供了结构。框架是任何正在开发的应用程序的基础。糟糕的基础会导致糟糕的应用程序,需要更多的维护成本,并且本质上效率低下。因此,无论何时决定开发框架,都要寻找在该特定业务领域具有丰富设计经验的领域专家,这样,您将能够开发出可重用且可扩展的软件。

祝你好运!

干杯。

电子邮件: shams_mukhtar@yahoo.com

© . All rights reserved.