zoukankan      html  css  js  c++  java
  • .NET设计模式(2):1.2 抽象工厂模式(Abstract Factory)

    大话设计模式-抽象工厂模式-结构图

    概述

    抽象工厂模式(Abstract Factory)是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。


    定义

    抽象工厂模式(Abstract Factory),提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。


    UML图解

    • AbstractFactory:声明一个创建抽象产品对象的操作接口

    • ConcreteFactory:实现创建具体产品对象的操作

    • AbstractProduct:声明一类产品对象接口

    • Product

      • 定义一个被相应具体工厂创建的产品对象

      • 实现AbstractProduct接口

    • Client:使用AbstractFactory和AbstractProduct类声明的接口

      在抽象工厂模式中,产品的创建由ConcreteFactory来完成,从结构图中可以看出,抽象工厂模式的ConcreteFactory不是负责一种具体Product的创建,而是负责一个Product族的创建。


    实现

    说明:
    1.本次实现以博客系统为例,抽取其中的用户和文章两个对象进行说明。
    2.采用三层架构,为了省事,去掉了业务逻辑层(BLL),希望理解。

    示例项目结构图
    抽象工厂模式实现-示例项目结构

    示例项目类图
    抽象工厂模式实现-示例项目类图

    • Blog.Models:模型层
    • Blog.IDAL:数据访问层接口(一类产品对象接口[AbstractProduct])
    • Blog.DAL:数据访问层分类实现(抽象产品具体分类实现)
      • MsSql:MsSql实现(抽象产品具体分类实现[ProductA1,ProductA2])
      • MySql:MySql实现(抽象产品具体分类实现[ProductB1,ProductB2])
    • Blog.Factory:抽象工厂层
      • lFactory:抽象工厂接口([AbstractFactory])
      • MsSqlFactory:MsSql具体工厂(创建具体产品对象的操作[ConcreteFactory1])
      • MySqlFactory:MySql具体工厂(创建具体产品对象的操作[ConcreteFactory2])

    模型层(Blog.Models)

    • UserModel
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace AbstractFactorySamlpe.Blog.Models
    {
        public class UserModel
        {
            public int UserId { get; set; }
            public string UserName { get; set; }
            public string Password { get; set; }
        }
    }
    
    • PostModel
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace AbstractFactorySamlpe.Blog.Models
    {
        public class PostModel
        {
            public int PostId { get; set; }
            public string PostTitle { get; set; }
            public string PostContent { get; set; }
            public DateTime PostTime{ get; set; }
            public int PostUser { get; set; }
        }
    }
    

    数据访问层接口(Blog.IDAL)

    • IUserDAL
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using AbstractFactorySamlpe.Blog.Models;
    
    namespace AbstractFactorySamlpe.Blog.IDAL
    {
        public interface IUserDAL
        {
            bool Insert(UserModel model);
    
            UserModel GetById(int id);
    
            bool Update(UserModel model);
    
            bool Delete(int id);
        }
    }
    
    • IPostDAL
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using AbstractFactorySamlpe.Blog.Models;
    
    namespace AbstractFactorySamlpe.Blog.IDAL
    {
        public interface IPostDAL
        {
            bool Insert(PostModel model);
    
            PostModel GetById(int id);
    
            bool Update(PostModel model);
    
            bool Delete(int id);
        }
    }
    

    数据访问层分类具体实现(Blog.DAL)

    • Blog.DAL.MsSql
      • MsSqlPostDAL
    using AbstractFactorySamlpe.Blog.IDAL;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using AbstractFactorySamlpe.Blog.Models;
    
    namespace AbstractFactorySamlpe.Blog.DAL.MsSql
    {
        public class MsSqlPostDAL : IPostDAL
        {
            public bool Delete(int id)
            {
                return true;
            }
    
            public PostModel GetById(int id)
            {
                return new PostModel();
            }
    
            public bool Insert(PostModel model)
            {
                return true;
            }
    
            public bool Update(PostModel model)
            {
                return true;
            }
        }
    }
    
    • MsSqlUserDAL
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using AbstractFactorySamlpe.Blog.IDAL;
    using AbstractFactorySamlpe.Blog.Models;
    
    namespace AbstractFactorySamlpe.Blog.DAL.MsSql
    {
        public class MsSqlUserDAL : IUserDAL
        {
            public bool Delete(int id)
            {
                return true;
            }
    
            public UserModel GetById(int id)
            {
                return new UserModel();
            }
    
            public bool Insert(UserModel model)
            {
                return true;
            }
    
            public bool Update(UserModel model)
            {
                return true;
            }
        }
    }
    
    • Blog.DAL.MySql
      • MySqlPostDAL
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using AbstractFactorySamlpe.Blog.IDAL;
    using AbstractFactorySamlpe.Blog.Models;
    
    namespace AbstractFactorySamlpe.Blog.DAL.MySql
    {
        public class MySqlPostDAL : IPostDAL
        {
            public bool Delete(int id)
            {
                return true;
            }
    
            public PostModel GetById(int id)
            {
                return new PostModel();
            }
    
            public bool Insert(PostModel model)
            {
                return true;
            }
    
            public bool Update(PostModel model)
            {
                return true;
            }
        }
    }
    
    • MySqlUserDAL
    using AbstractFactorySamlpe.Blog.IDAL;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using AbstractFactorySamlpe.Blog.Models;
    
    namespace AbstractFactorySamlpe.Blog.DAL.MySql
    {
        public class MySqlUserDAL : IUserDAL
        {
            public bool Delete(int id)
            {
                return true;
            }
    
            public UserModel GetById(int id)
            {
                return new UserModel();
            }
    
            public bool Insert(UserModel model)
            {
                return true;
            }
    
            public bool Update(UserModel model)
            {
                return true;
            }
        }
    }
    

    抽象工厂(Blog.Factory)

    • IFactory
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using AbstractFactorySamlpe.Blog.IDAL;
    
    namespace AbstractFactorySamlpe.Blog.Factory
    {
        public interface IFactory
        {
    
            IUserDAL CreateUser();
    
            IPostDAL CreatePost();
        }
    }
    
    • MsSqlFactory
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using AbstractFactorySamlpe.Blog.DAL.MsSql;
    using AbstractFactorySamlpe.Blog.IDAL;
    
    namespace AbstractFactorySamlpe.Blog.Factory
    {
        public class MsSqlFactory : IFactory
        {
            public IPostDAL CreatePost()
            {
                return new MsSqlPostDAL();
            }
    
            public IUserDAL CreateUser()
            {
                return new MsSqlUserDAL();
            }
        }
    }
    
    • MySqlFactory
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using AbstractFactorySamlpe.Blog.DAL.MySql;
    using AbstractFactorySamlpe.Blog.IDAL;
    
    namespace AbstractFactorySamlpe.Blog.Factory
    {
        public class MySqlFactory : IFactory
        {
            public IPostDAL CreatePost()
            {
                return new MySqlPostDAL();
            }
    
            public IUserDAL CreateUser()
            {
                return new MySqlUserDAL();
            }
        }
    }
    

    调用(Client)

    Program

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using AbstractFactorySamlpe.Blog.Factory;
    using AbstractFactorySamlpe.Blog.IDAL;
    
    namespace AbstractFactorySamlpe
    {
        class Program
        {
            static void Main(string[] args)
            {
                //MSSQL
                //IFactory factory = new MsSqlFactory();
                //IUserDAL UserDAL = factory.CreateUser();
                //IPostDAL PostDAL = factory.CreatePost();
    
                //MySQL
                IFactory factory = new MySqlFactory();
                IUserDAL UserDAL = factory.CreateUser();
                IPostDAL PostDAL = factory.CreatePost();
            }
        }
    }
    

    Client

    优点:

    1、封装性,每个产品的实现类不是高层模块要关心的。
    2、产品族内的约束为非公开状态。

    缺点:

    产品族扩展非常困难。

    使用场景:

    一个对象族或是一组没有任何关系的对象都有相同的约束,则可以使用抽象工厂模式。

    注意事项:
    产品族扩展困难,产品等级非常容易扩展,也就是横向扩展容易,纵向扩展困难。

  • 相关阅读:
    nginx location 语法
    nginx 日志文件
    nginx 配置文件详解
    mysql分区partition
    MySQL跳过密码登录
    min/max优化,count ,group by
    in型子查询陷阱,exists子查询
    explain分析sql效果
    HDU2896 病毒侵袭 —— AC自动机
    二分图之 多重匹配 和 最大权匹配 等总结
  • 原文地址:https://www.cnblogs.com/seayxu/p/design-pattern-for-dotnet-abstract-factory.html
Copyright © 2011-2022 走看看