标签归档:设计模式

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# 建造者模式


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



建造者模式简介

按照一定的接口规范扩展一个类,我们都可以把这种设计风格称之为“建造者模式”。
使用建造者模式可以保证一个实例对象的创建,都是采用同一的流程进行构造。
常见的建造者模式: 建设大厦的流程
1 首先 打桩
2 建地下车库
3 开始建设框架
4 外墙装修
5 内部设施(水电)安装
6 内装
7 交付使用


建造者模式组成:
Builder:一个抽象接口,为产品类指定抽象接口。
ConcreteBuilder:
实现Builder抽象接口,使用此接口构造各部分
提供一个返回产品的接口
Director:
调用创建者(builder)组建产品,运行builder抽象接口中的方法生成产品,
在Director中规定了建造产品的流程
Product:
建造完成的实体对象放入此类中进行存储和此类可以对外展示实体的各种功能


建造者模式的优点:
1 使用建造者模式可以使建造某一产品的工序得到有效的封装,建造顺序得到有效的封装,保证了系统稳定性。
2 建造者模式易于扩展,当有新的产品产生时,可以通过引入一个新的ConcreteBuilder来完成新的产品创建


建造者模式应用场景

支持多种数据库的 DB操作类是一种近似建造者模式的实现。
创建具有相同属性的一类对象。

下文将举例使用建造者模式的设置大厦属性(使用建造者模式构建操作类)

 /*设置产品类*/

 public class Product {  
    private String   builderName;  
    private DateTime builderDate;  
    public void showProduct(){  
        Console.WriteLine("大厦名称:"+builderName);  
        Console.WriteLine("建造年份:"+builderDate);  
    }  
    public void setBuilderName(String builderName) {  
        this.builderName = builderName;  
    }  
    public void setDate(String builderDate) {  
        this.builderDate = builderDate;  
    }  
}  

  

/*
设置一个抽象接口
*/
abstract class Builder {  
    public abstract void setPart(String arg1, String arg2);  
    public abstract Product getProduct();  
}  



class ConcreteBuilder:Builder {  
    private Product product = new Product();  
      
    public Product getProduct() {  
        return product;  
    }  
  
    public void setPart(String arg1, String arg2) {  
        product.setBuilderName(arg1);  
        product.setDate(arg2);  
    }  
}  
  
public class Director {  
    private Builder builder = new ConcreteBuilder();  
    public Product getAProduct(){  
        builder.setPart("maomao365.com大厦",(DateTime)"2017-2-6");  
        return builder.getProduct();  
    }  
    public Product getBProduct(){  
        builder.setPart("猫猫小屋",(DateTime)"2017-3-6");  
        return builder.getProduct();  
    }  
}  


/*
客户端应用
*/
public class Client {  
    public static void main(String[] args){  
        Director director = new Director();  
        Product product1 = director.getAProduct();  
        product1.showProduct();  
  
        Product product2 = director.getBProduct();  
        product2.showProduct();  
    }  
}