一步一步搭架子(Model继承与Factory层)

一直觉得,简单也是一种美,架构如此,做人亦如此;重剑无锋,真水无香

为了便于大家理解,在此放出源代码:点击此处下载

强烈建议配合代码阅读本文,毕竟代码才是程序员最好的交流方式

 

之前的文章分析了系统,并画出了架构草图,详情请见《一步一步搭架子(分析篇)

关于ModelBase层与Model层的实现,因为很简单,就不再赘述了,直接上代码即可。关于Model继承的思路,请见:《我们该如何设计数据库(三)(续)

ModelBase代码:

namespace ModelBase

{

    public class Identifier

    {

        [Key]

        public Guid ID { get; set; }

    }



    public class TeacherBase : Identifier

    {

        [StringLength(50)]

        public string UserName { get; set; }



        [StringLength(50)]

        public string Pwd { get; set; }

    }



    public class ContactBase : Identifier

    {

        [Required]

        public Guid TeacherID { get; set; }



        [StringLength(50)]

        public string Phone { get; set; }



        [StringLength(50)]

        public string Email { get; set; }

    }

}

可以看到,数据在这一层是还没有组合在一起的;然后是Model代码(假设现在是提供给A学校的):

namespace Model.A

{

    public class Teacher : TeacherBase

    {

        [StringLength(50)]

        public string FirstName { get; set; }



        [StringLength(50)]

        public string LastName { get; set; }



        public Contact Contact { get; set; }

    }



    public class Contact : ContactBase

    {

        public DateTime CreateTime { get; set; }

    }

}

可以看到,Teacher中包含了Contact。我习惯称这种为“数据耦合在一起”,虽然我不知道这种叫法对不对。欢迎留言指正这种说法

请注意,这里用Model.A的命名空间来区分了Model。如果是B学校的Model,要这样写:

namespace Model.B

{

    public class Teacher : TeacherBase

    {

        [StringLength(50)]

        public string Number { get; set; }

    }



    public class Contact : ContactBase

    {

    }

}

可以看到,A学校和B学校Model的命名都是Teacher 和Contact ,用不同的命名空间来加以区分

 

再然后是DBcontext的实现:

using System.Data.Entity;

using Model.A;



namespace DBaccess.A

{

    public class Context : DbContext

    {

        public Context()

        {

            //this.Configuration.AutoDetectChangesEnabled = false;

            //this.Configuration.LazyLoadingEnabled = true;

            //this.Configuration.ProxyCreationEnabled = false;

            //this.Configuration.ValidateOnSaveEnabled = false;

        }



        public DbSet<Teacher> Teacher { get; set; }

        public DbSet<Contact> Contact { get; set; }



        protected override void OnModelCreating(DbModelBuilder modelBuilder)

        {

            modelBuilder.Entity<Teacher>()

                .Ignore(o => o.Contact);          //Teacher中的Contact不映射到数据库中

        }     

    }

}

 

然后就是系统中的难点:Factory的设计

一开始,我觉得这个就是抽象工厂模式所描述的应用场景:同类产品不同产品族的开发

但是在实际开发过程中,却发现抽象工厂无法满足需要。抽象工厂要求子类从基类派生,这点我们的Model是由ModelBase派生的,满足条件;但是我们不同的Model还有自己独有的get/set方法,而这些独有的方法是无法通过抽象工厂完成的

简单的反射也无法满足要求。反射出来的是一个Object类型,要通过as关键字转换之后才能使用,如:

            Object obj = Assembly.Load("").CreateInstance("");   //假设这里反射出一个Teacher

            Teacher teacher = obj as Teacher;                    //还要as之后才能使用

 

我在这个问题上耗费了一个星期多的时间,直到有一天,灵感突现:可以使用预编译指令来实现NameSpace的切换

#define A

#if B

using Model.B;

using DBaccess.B;

#endif

#if A

using Model.A;

using DBaccess.A;

#endif

这样的话,我们切换Model,只需将#define A改为#define B

Factory的具体实现如下:

#region NameSpace

#define A

#if B

using Model.B;

using DBaccess.B;

#endif

#if A

using Model.A;

using DBaccess.A;

#endif

#endregion

using System.Collections.Generic;



namespace Factory

{

    public class ModelFactory

    {

        public static Teacher GetTeacher()

        {

            return new Teacher();

        }       



        public static Contact GetContact()

        {

            return new Contact();

        }   

    }



    public class ModelListFactory

    {

        public static IList<Teacher> GetTeacherList()

        {

            return new List<Teacher>();

        }



        public static IList<Contact> GetContactList()

        {

            return new List<Contact>();

        }

    }



    public class ContextFactory

    {

        public static Context GetContext()

        {

            return new Context();

        }

    }

}

这样弄出来的Factory,如其名字一样,用了最简单的工厂模式来实现

 

就此搁笔

 

PS:变天了,各位园友记得防寒保暖  :)

你可能感兴趣的:(factory)