跳转到内容

C# 编程/设计模式

来自维基教科书,开放书籍,开放世界

设计模式是为解决日常软件问题而设计的通用构建块。我们在日常生活中看到的某些基本术语和此类模式的示例。设计模式大体上分为 3 类

1. 创建型: 这些模式专为类实例化而设计。它们可以是类创建模式或对象创建模式。

2. 结构型: 这些模式是针对类的结构和组合而设计的。大多数这些模式的主要目标是增加所涉及的类(es)的功能,而无需对其组合进行太多更改。

3. 行为型: 这些模式是根据一个类如何与其他类通信而设计的。


工厂模式

[编辑 | 编辑源代码]

工厂模式是一种方法调用,它使用抽象类及其实现,为开发人员提供最适合工作的类。

让我们先创建几个类来演示如何使用它。这里我们以银行系统为例。

public abstract class Transaction
{
     private string _sourceAccount;

     // May not be needed in most cases, but may on transfers, closures and corrections.
     private string _destinationAccount;
   
     private decimal _amount;
     public decimal Amount { get { return _amount; } }
   
     private DateTime _transactionDate;
     private DateTime _effectiveDate;

     public Transaction(string source, string destination, decimal amount)
     {
          _sourceAccount = source;
          _destinationAccount = destination;
          _amount = amount;
          _transactionDate = DateTime.Now;
     }

     public Transaction(string source, string destination, decimal amount, DateTime effectiveDate) : this(source, destination, amount)
     {
          _effectiveDate = effectiveDate;
     }

     protected decimal AdjustBalance(string accountNumber, decimal amount)
     {
          decimal newBalance = decimal.MinValue;

          using(Mainframe.ICOMInterface mf = new Mainframe.COMInterfaceClass())
          {
               string dateFormat = DateTime.Now.ToString("yyyyMMdd HH:mm:ss");
               mf.Credit(dateFormat, accountNumber, amount);
               newBalance = mf.GetBalance( DateTime.Now.AddSeconds(1), accountNumber);
          }
          
          return newBalance;
     }
     
     public abstract bool Complete();
}

此 Transaction 类不完整,因为存在多种类型的交易

  • 开户
  • 存款
  • 取款
  • 转账
  • 罚款
  • 更正
  • 销户

对于此示例,我们将使用存款和取款部分,并为它们创建类。

public class Credit : Transaction
{
     // Implementations hidden for simplicity

     public override bool Complete()
     {
          this.AdjustBalance( _sourceAccount, amount);
     }
}

public class Withdrawal : Transaction
{
     // Implementations hidden for simplicity

     public override bool Complete()
     {
          this.AdjustBalance( _sourceAccount, -amount);
     }
}

问题是这些类做了很多相同的事情,因此如果我们可以只提供值,它就会确定我们需要的类类型,这将非常有用。因此,我们可以想出一些方法来区分不同类型的交易

  • 正值表示存款。
  • 负值表示取款。
  • 有两个帐号和一个正值表示转账。
  • 有两个帐号和一个负值表示销户。
  • 等等。

所以,让我们编写一个新的类,其中包含一个静态方法,该方法将为我们完成此逻辑,并将名称结尾为 Factory

public class TransactionFactory
{
     public static Transaction Create( string source, string destination, decimal amount )
     {
          if(!string.IsNullOrEmpty(destination) )
          {
               if(amount >= 0)
                    return new Credit( source, null, amount);
               else
                    return new Withdrawal( source, null, amount);
          }
          else
          {
               // Other implementations here
          }
     }
}

现在,您可以使用此类来执行所有逻辑和处理,并确保您返回的类型是正确的。

public class MyProgram
{
     static void Main()
     {
          decimal randomAmount = new Random().Next()*1000000;
          Transaction t = TransactionFactory.Create("123456","",randomAmount);
          // t.Complete(); <-- This would carry out the requested transaction.
 
          Console.WriteLine("{0}: {1:C}",t.GetType().Name, t.Amount);
     }
}

单例模式

[编辑 | 编辑源代码]

单例模式只实例化 1 个对象,并在整个进程生命周期中重复使用此对象。如果您希望对象保持状态,或者设置对象需要大量资源,这将非常有用。以下是基本实现

public class MySingletonExample
{
   private static object obj = new object();
   private volatile static Hashtable _sharedHt;

   public static Hashtable Singleton
   {
     get 
      {
         if(_sharedHt == null){
             lock(obj){
                  if(_sharedHt == null){
                     _sharedHt = new Hashtable();
                  }
             }
         }
         return _sharedHt;
      }
      // set { ; }
     // Not implemented for a true singleton
   }

   // Class implementation here..
}

Singleton 属性将向所有调用者公开相同的实例。在第一次调用时,对象被初始化,并在后续调用中使用此对象。

此模式的示例包括

  • ConfigurationSettings (通用设置读取器)
  • HttpApplication (ASP .NET 中的应用程序对象)
  • HttpCacheUtility (ASP .NET 中的缓存对象)
  • HttpServerUtility (ASP .NET 中的服务器对象)
华夏公益教科书