.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、产品族内的约束为非公开状态。

缺点:

产品族扩展非常困难。

使用场景:

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

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


seay
个人学习笔记
767 声望
32 粉丝
0 条评论
推荐阅读
在 Windows Forms 和 WPF 应用中使用 FontAwesome 图标
FontAwesome 大家都不陌生,精美的图标,出现在各式各样的网页中。最近在做 Windows Forms 应用程序,要求美观,就想能不能把 FontAwesome 图标用上,于是就有了本文。

Seay阅读 3.2k评论 4

工作中常用的设计模式--享元模式
一般做业务开发,不太容易有大量使用设计模式的场景。这里总结一下在业务开发中使用较为频繁的设计模式。当然语言为Java,基于Spring框架。

lpe2344阅读 992

封面图
面试的时候别再说你不会设计模式了
最近在设计一个对某个中间件的测试方案,这个测试方案需要包含不同的测试逻辑,但相同的是需要对各个环节进行记录;比如统计耗时、调用通知 API 等相同的逻辑。

crossoverJie阅读 1.1k

设计模式那些事(4)——常见结构型模式在Go中的应用
上一篇创建型(单例/工厂/建造者)设计模式在Go中的应用介绍了一些常见的创建型设计模式,创建型主要解决了类的创建问题,使代码更易用,而我们经常遇到另外一种问题:类或对象如何组合在一起效率更高,结构型模...

爆裂Gopher1阅读 620评论 1

封面图
设计模式那些事(3)——使用建造者模式封装go的http库
{代码...} 具体实现 {代码...} 使用 {代码...}

爆裂Gopher1阅读 775

封面图
ASP.NET连接数据库(SQL Server)的操作
1.创建好项目后在我们的Web.config里面连接SQL Server数据库2.写入代码 {代码...} conStr是字段名字,后面连接需要,localhost是本地地址的意思,s是数据库中的表名。3.选中shujuku练习右击,选择添加,然后在选...

HealerHong3阅读 725评论 1

(持续更新,已更新至2022年11月26日)C语言经典题集合
(持续更新,最新时间2022年11月26日)1. 三个数由小到大排序输入任意3个整数,编程实现对这3个整数进行由小到大排序井将排序后的结果显示在屏幕上 {代码...} 2. a²+b²要求输入整数a和 b, 若a²+b²的结果大与100, ...

瞿小凯阅读 1.4k评论 2

封面图
767 声望
32 粉丝
宣传栏