.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();
}
}
}

优点:
1、封装性,每个产品的实现类不是高层模块要关心的。
2、产品族内的约束为非公开状态。
缺点:
产品族扩展非常困难。
使用场景:
一个对象族或是一组没有任何关系的对象都有相同的约束,则可以使用抽象工厂模式。
注意事项:
产品族扩展困难,产品等级非常容易扩展,也就是横向扩展容易,纵向扩展困难。
.NET设计模式(2):1.2 抽象工厂模式(Abstract Factory)的更多相关文章
- 设计模式之十一:抽象工厂模式(Abstract Factory)
抽象工厂模式: 提供了一个创建一系列相关的或相互依赖的对象的接口而不须要详细指定它们的类型. Provide an interface for creating families of related ...
- 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern)
原文:乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factor ...
- 【设计模式】抽象工厂模式 Abstract Factory Pattern
简单工厂模式是一个工厂类根据工厂方法的参数创建不出不同的产品, 工厂方法模式是每一个产品都有一个一一对应的工厂负责创建该产品.那么今天要讲的抽象工厂模式是一个工厂能够产生关联的一系列产品.抽象工厂模式 ...
- 设计模式 - 抽象工厂模式(abstract factory pattern) 具体解释
抽象工厂模式(abstract factory pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/2709 ...
- 二十四种设计模式:抽象工厂模式(Abstract Factory Pattern)
抽象工厂模式(Abstract Factory Pattern) 介绍提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 示例有Message和MessageModel,Messag ...
- 【UE4 设计模式】抽象工厂模式 Abstract Factory Pattern
概述 描述 提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类:具体的工厂负责实现具体的产品实例 抽象工厂中每个工厂可以创建多种产品(如苹果公司生产iPhone.iPad): 工厂方法 ...
- 抽象工厂模式(Abstract Factory)C#实例
抽象工厂模式(Abstract Factory)C#实例 本文出处http://www.dofactory.com/net/abstract-factory-design-pattern 一.场景描述 ...
- 设计模式08---设计模式之抽象工厂模式(Abstract Factory)
1.场景模拟 举个生活中常见的例子:组装电脑,我们在组装电脑的时候,通常要选择一系列的配件,比如选择CPU时候,需要注意品牌,型号,针脚数目,主频,只有这些都确定下来,才能确定一个CPU.同样,主板也 ...
- 设计模式的征途—3.抽象工厂(Abstract Factory)模式
上一篇的工厂方法模式引入了工厂等级结构,解决了在原来简单工厂模式中工厂类职责太重的原则,但是由于工厂方法模式的每个工厂只生产一类产品,可能会导致系统中存在大量的工厂类,从而增加系统开销.那么,我们应该 ...
随机推荐
- winform设置文本框宽度 根据文字数量和字体返回宽度
_LinkLabel.Width = TextRenderer.MeasureText(_LinkLabel.Text, _LinkLabel.Font).Width;
- Android安全开发之ZIP文件目录遍历
1.ZIP文件目录遍历简介 因为ZIP压缩包文件中允许存在“../”的字符串,攻击者可以利用多个“../”在解压时改变ZIP包中某个文件的存放位置,覆盖掉应用原有的文件.如果被覆盖掉的文件是动态链接s ...
- golang reflect
golang reflect go语言中reflect反射机制.详细原文:地址 接口值到反射对象 package main import ( "fmt" "reflect ...
- 【VC++技术杂谈003】打印技术之打印机状态监控
在上一篇博文中我主要介绍了如何获取以及设置系统的默认打印机,本文将介绍如何对打印机状态进行实时监控,记录下所打印的文档.打印的份数以及打印时间等打印信息. 1.打印机虚脱机技术 在正式介绍如何对打印机 ...
- AngularJs之一
在讲正题之前,先说一下有关angular简介方面的信息: 1. angularJS 诞生于2009年,由Misko Hevery 等人创建,后为Google所收购.是一款优秀的前端JS框架,已经被用 ...
- easyui相关script的配置
<!-- 1 jQuery的js包 --> <script type="text/javascript" src="jquery-easyui-1.4. ...
- HTTP学习二:Web应用中的HTTP
1 HTTP连接 1.1 TCP连接对性能的影响 TCP三次握手如下图: 如上图,建立一次TCP连接要经过三个步骤.HTTP是建立在TCP之上的,因此TCP连接的性能直接影响HTTP的性能. TCP影 ...
- C++中static数据成员详解
本文和大家分享的主要是c++中static数据成员的相关用法及源码示例,希望能帮助大家更好的学习C++. static(静态存储)数据成员 StaticTest.cpp : 定义控制台应用程序 ...
- ECMAScript6学习笔记 ——let、const、变量解构赋值
let 不存在变量提升 通过let声明的变量仅在块级作用域内有效 不允许在同一个作用域内重复声明一个变量 防止值公用 var oUl = document.querySelectorAll('ul&g ...
- SQL Server 无法生成 FRunCM 线程。请查看 SQL Server 错误日志和 Windows 事件日志
1.IP地址配置不正确: 打开 Microsoft SQL Server 2005配置工具下的SQL Server Configuration Manager,选择MSSQLSERVER协议, 然后双 ...