zoukankan      html  css  js  c++  java
  • 简单工厂-基于接口的编程

    昨天,老师给我们展示了简单工厂的设计模式。今天练习了一遍,体会了一下面向接口的编程的强大之处。今天总结一下,加深一下理解。

    因为初学C#.net编程,之前做的几个例子都是使用的简单三层架构。而简单三层有个问题,业务操作类与数据操作类是强耦合关系,数据操作类的变动,会直接影响到业务操作类的正常运行,所以为了解决这个问题,需要解耦。怎么解耦,引入接口和工厂类,来将业务操作类与数据操作类的关系变为弱耦合关系。

     

    如左图,图中每条线都代表一个类,图A是一种强耦合关系,一个类的变动就会影响其他类;图B在两个类有关系的地方定义了一个接口,这样类A如何改变都不会影响到类B,这样就达到了解耦的目的,这就是面向接口的编程模式。

     

     

     

     

     

     

    下附上两个图来说明下思路:

    图A为简单三层,如果数据访问类发生改变(比如:换个数据帮助类文件,就需要修改业务逻辑类里的代码),这样会重复写许多相同的代码。

    图B为简单工厂,在业务逻辑类与UI层添加一个接口(I1),在数据访问层与业务逻辑层之间再添加一个接口(I2)。这样不同数据访问层只需要实现I2既可以

    思路已经有了,如何用代码实现呢?下面以查询为例简单介绍:

    数据访问层代码:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using Test.Model;
     6 using System.Data;
     7 using System.Data.SqlClient;
     8 namespace Test.SqlServerDAL
     9 {
    10     //Student的数据访问层,实现IStudentDAL接口
    11     public class StudentDAL : IDAL.IStudentDAL
    12     {
    13         //获取所有Student并加入List<Student>中
    14         public List<Model.Student> GetAllStudent()
    15         {
    16             List<Student> list = new List<Student>();
    17             Student stu;
    18             string sqlText = "select stuId, stuName, stuAge, stuGender, stuPhone, stuEmail, stuAddress, stuSchool from Student";
    19             using (SqlDataReader sdr = SQLHelper.ExecuteReader(sqlText, CommandType.Text))
    20             {
    21                 while (sdr.Read())
    22                 {
    23                     stu = new Student();
    24                     stu.StuId = sdr.GetInt32(0);
    25                     stu.StuName = sdr.GetString(1);
    26                     stu.StuAge = sdr.GetInt32(2);
    27                     stu.StuGender = sdr.GetString(3);
    28                     stu.StuPhone = sdr.GetString(4);
    29                     stu.StuEmail = sdr.GetString(5);
    30                     stu.StuAddress = sdr.GetString(6);
    31                     stu.StuSchool = sdr.GetString(7);
    32 
    33                     list.Add(stu);
    34                 }
    35             }
    36             return list;
    37         }
    38     }
    39 }
    View Code

    子类接口:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using Test.Model;
     6 
     7 namespace IDAL
     8 {
     9     //子类接口
    10     public interface IStudentDAL:IBaseDAL<Student>
    11     {
    12         List<Student> GetAllStudent();//获取所有学生
    13         //增删改方法
    14     }
    15 }

    基类接口,可以封装增删改查方法(只写了查询的方法):

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 
     6 namespace IDAL
     7 {
     8     //基类接口,可以封装增删改查方法,使用了泛型便于获取不同类型的实体,让有相同方法的子类继承,并且给出特定类型。where T:class,new()意思是一个限制,T是一个类,并且可以new(),有个无参的构造函数
     9     public interface IBaseDAL<T> where T:class,new()
    10     {
    11         List<T> GetAllStudent();
    12     }
    13 }

    工厂类,用于创建数据访问层对象

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using Test.SqlServerDAL;
     6 namespace StudentFactoryDAL
     7 {
     8     public class FactoryDAL
     9     {
    10         //静态工厂类,用来创建对应的DAL对象
    11         public static IDAL.IStudentDAL CreateStudentDAL() 
    12         {
    13             return new StudentDAL();
    14         }
    15     }
    16 }

    业务逻辑层

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using Test.Model;
     6 
     7 namespace Test.BLL
     8 {
     9     public class StudentBLL:IBLL.IStudentBLL
    10     {
    11         //通过接口和工厂创建DAL对象
    12         IDAL.IStudentDAL dal = StudentFactoryDAL.FactoryDAL.CreateStudentDAL();
    13         //调用dal中的方法,获取所有的学生信息并传给UI层
    14         public List<Student> GetAllStudent()
    15         {
    16             return dal.GetAllStudent();
    17         }
    18     }
    19 }

    同理,可以让业务逻辑层实现接口,并且通过工厂类在表示层后台创建BLL对象,实现业务逻辑层与表现层的解耦。

    这样,面向接口的编程就实现了,无论数据访问层怎么修改,只要让它实现上述例子中的子接口就可以了。抽象工厂就是让工厂通过配置文件来动态创建相应的对象,这样更加增加了代码的灵活性。

    以上是我自己的理解,如果有错误,还希望大牛们能给指出,谢谢。

  • 相关阅读:
    团队活动
    实力提升
    软工人必须要知道的几个工具
    博客/论坛:(技术分享)
    CSS怎样设置多个字体,设置多个字体的时候要注意什么
    canvas绘制bitmap全部填充(当bitmap的宽高小于绘制区域的时候)
    CSS字体
    weditor元素定位异常
    python ImportError: C extension: DLL load failed while importing strptim
    python:导入不同路径下相同名称的模块
  • 原文地址:https://www.cnblogs.com/JokerYang/p/3422003.html
Copyright © 2011-2022 走看看