月度归档:2017年03月

c# 面向对象设计模式–简单工厂模式


面向对象基础:抽象 封装 多态 继承
面向对象原则:封装变化 多用组合 少用继承 针对接口编程 依赖抽象 不依赖具体 尽量松耦合 对修改关闭 对扩展开放


前言:
工厂模式的主要思想:
将对象的创建放入工厂中,当有新的类型的子对象产生时,只需要修改工厂方法,就可以使当前类支持新的类型,易于系统维护。
在系统开发中,我们常将工厂模式应用于DB层,使DB层可以生产出“多种数据库操作类”,来应对系统的各种变化。




工厂模式的产生

一个业务应用类A
一个数据库实现包B(namespace B) (B中包含 MSSQL操作类 class MSSQL{} MySql操作类 class MySql{} Oracle操作类 class Oracle{} DB2操作类 class DB2{} …)
当A中需要使用数据库操作时,假如此时我们需要使用MSSQL操作类,这时,我们需要new一个操作对象

 class A{
    DB db;    
    db = new MSSQL();
      /*
       在实际业务中,此处使用了具体类会导致程序不具有扩展性
       当我们切换其它数据库时,需改写所有应用类中的代码
      */
  }
  
  
class A{ DB db; if (dbType =="MSSQL") { db = new MSSQL(); }else if(dbType =="MySql") { db = new MySql(); }else if(dbType =="Oracle") { db = new Oracle(); } ... /* 在实际业务中,当我们扩展一个数据库时,所有的应用代码都必须修正 */ }


以上两种应用代码的写法,当有变化或扩展时,就必须重新打开应用类代码进行检查和修改,由于有大量的修改,会加大系统的修改的错误几率,并且违背了”对修改关闭”的原则
所以为了修正以上,我们必须采用一种全新的编程方式,那么就是针对”接口编程”,因为针对接口编写的代码,可以支持多态,它可以关联任何实现此接口的类。



封装db对象的创建代码

  class A{
    DB db;
    /*将创建对象的代码进行抽离放入一个新的对象(DbFactory),这个新对象负责进行的创建*/
     ...
     /*应用相关操作*/
   }
   
  class DbFactory{
    
    public Db DbFactory()
     {
      Db db; //Db为interface
      if (dbType =="MSSQL")
      {
       db = new MSSQL();
      }else if(dbType =="MySql")
      {
       db = new MySql();
      }else if(dbType =="Oracle")
      {
       db = new Oracle();
      }
      return Db;
    }
  }


我们将DbFactory这个新对象称之为”工厂”。
工厂对象主要是处理创建对象。由于有了DbFactory对象后,当应用类A需要使用数据库操作对象时,需调用工厂类产生数据库操作类,
从class A class DbFactory 我们可以看出,DbFactory工厂主要为应用类A提供Db操作类服务。



创建一个简单DB工厂

   class DbSimpleFactory{
    
    public Db CreateDb(string  dbType)   //简单工厂中,定义一个CreateDb方法,所有客户使用这个方法来实例化新的对象
     {
      Db db = null; //Db为interface
      if (dbType =="MSSQL")
      {
       db = new MSSQL();
      }else if(dbType =="MySql")
      {
       db = new MySql();
      }else if(dbType =="Oracle")
      {
       db = new Oracle();
      }
      return Db;
    }
  }


简单工厂的优点:
当增加新的数据库对象时,系统易于修改,便于维护
可以使对象在运行时,动态的组合当前符合条件的类

c# 原型模式实现方式


一、原型模式简介

原型模式是指一个对象可以通过原型对象中的方法创建更多相同类型的对象,我们将这种操作方式称之为“原型模式”。


二、原型模式应用场景

当一个通过new对象生成一个新的对象非常复杂(需要进行大量的数据准备),此时就需要使用原型模式。
如果一个对象中元素信息都是值类型,那么都是浅拷贝可以高效快速的复制一个全新的对象。


三、原型模式实现

  using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace bossManage
{
     
    #region 类定义
    class baseInfo : System.Object, ICloneable
    {
        public string nameTest = @"这是值类型原始数值"; //值类型 
        public object Clone()
        {
            return new baseInfo() as object; //深拷贝
        }


        public object shallowCopy()
        {
            return this.MemberwiseClone();
        }

        public object thisCopy()
        {
            return this as object;
        }
    }

    #endregion


    public partial class test2 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            #region  原型模式应用
            baseInfo main = new baseInfo();  //源对象             
            baseInfo deepMain = main.Clone() as baseInfo; //通过原型模式生成新的对象 
  
            #endregion

        }
    }
}

相关阅读:
c# 深拷贝 浅拷贝

c# 深拷贝 浅拷贝


c# 深拷贝 浅拷贝 简介

深拷贝、浅拷贝在c#中都是对对象进行拷贝(复制、克隆),应用当前对象复制一个一模一样的对象。



深拷贝与浅拷贝的区别 :
对引用类型的处理不同
深拷贝对引用类型的处理方式,在新对象中创建一个新的对象和原始对象中对应 字段内容相同的字段。
浅拷贝 对非字符串的引用类型,只拷贝引用地址,所以 源对象中的引用类型的值变化会影响copy对象中的值。


深复制 操作方法:当前类需要实现ICloneable接口中的Clone方法,对可进行深拷贝的对象上需加上[Servializable]特性
浅复制 操作方法:使用Object类中的MemberwiseClone方法创建一个浅拷贝副本


c# 深拷贝 浅拷贝 举例测试

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace bossManage
{


    #region 引用类型定义

    class testInfo
    {
        public string nameTest2=@"这是引用类型默认值";
    }


    #endregion




    #region 类定义

    class baseInfo : System.Object, ICloneable
    {

        public string nameTest = @"这是值类型原始数值"; //值类型
        public testInfo nameTest2 = new testInfo();  //引用类型--当采用浅拷贝方式时,源对象或拷贝对象中的值发生变化时候,两个对象中的值都会发生变化
        public object Clone()
        {
            return new baseInfo() as object; //深拷贝
        }


        public object shallowCopy()
        {
            return this.MemberwiseClone();
        }

        public object thisCopy()
        {
            return this as object;
        }


    }

    #endregion


    public partial class test2 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

            #region 测试深拷贝 浅拷贝

            baseInfo main = new baseInfo();
            Response.Write("main对象:"+main.nameTest+"
"); Response.Write("深拷贝

"); //深拷贝 baseInfo deepMain = main.Clone() as baseInfo; Response.Write("main对象" + main.nameTest + " deepMain对象:" + deepMain.nameTest + "
"); Response.Write("main对象" + main.nameTest2.nameTest2 + " deepMain对象:" + deepMain.nameTest2.nameTest2 + "
"); deepMain.nameTest = @"深拷贝值类型数值改变!"; deepMain.nameTest2.nameTest2 = "引用类型深拷贝值改变"; Response.Write("main对象" + main.nameTest + " deepMain对象:" + deepMain.nameTest + "
"); Response.Write("main对象" + main.nameTest2.nameTest2 + " deepMain对象:" + deepMain.nameTest2.nameTest2 + "
"); Response.Write("浅拷贝

"); //浅拷贝 baseInfo shallowMain = main.shallowCopy() as baseInfo; Response.Write("main对象" + main.nameTest + " shallowMain对象:" + shallowMain.nameTest + "
"); Response.Write("main对象" + main.nameTest2.nameTest2 + " shallowMain对象:" + shallowMain.nameTest2.nameTest2 + "
"); shallowMain.nameTest = @"浅拷贝值类型数值改变!"; shallowMain.nameTest2.nameTest2 = "引用类型浅拷贝值改变"; Response.Write("main对象" + main.nameTest + " shallowMain对象:" + shallowMain.nameTest + "
"); Response.Write("main对象" + main.nameTest2.nameTest2 + " shallowMain对象:" + shallowMain.nameTest2.nameTest2 + "
"); Response.Write("同一对象

"); //同一对象 baseInfo thisMain = main.thisCopy() as baseInfo; Response.Write("main对象" + main.nameTest + " thisMain对象:" + thisMain.nameTest + "
"); Response.Write("main对象" + main.nameTest2.nameTest2 + " thisMain对象:" + thisMain.nameTest2.nameTest2 + "
"); thisMain.nameTest = @"this对象数值改变!"; thisMain.nameTest2.nameTest2 = "this对象值改变"; Response.Write("main对象" + main.nameTest + " thisMain对象:" + thisMain.nameTest + "
"); Response.Write("main对象" + main.nameTest2.nameTest2 + " thisMain对象:" + thisMain.nameTest2.nameTest2 + "
"); #endregion } } }

运行结果 如下图所示:
c#深拷贝浅拷贝运行结果