.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)模式
上一篇的工厂方法模式引入了工厂等级结构,解决了在原来简单工厂模式中工厂类职责太重的原则,但是由于工厂方法模式的每个工厂只生产一类产品,可能会导致系统中存在大量的工厂类,从而增加系统开销.那么,我们应该 ...
随机推荐
- gulp es7配置文件
http://sanwen.net/a/ybsfcoo.html /** * Created by udi on 2016/11/24. */ var gulp = require('gulp'); ...
- quick-cocos2d-x 2.2.3 rc版本中 crypto.md5file() 的C++实现在ANDROID上有BUG
原来的版本是用fopen打开文件的,如果要从ANDROID的APK中取文件,直接就洗白了修改如下 void CCCrypto::MD5File(const char* path, unsigned c ...
- windows命令——taskkill
C:\Users\Administrator>taskkill /? TASKKILL [/S system [/U username [/P [password]]]] { [/FI filt ...
- Atitit 索引技术--位图索引
Atitit 索引技术--位图索引 索引在数据结构上可以分为三种B树索引.位图索引和散列索引 存储原理 编辑 位图索引对数据表的列的每一个键值分别存储为一个位图,Oracle对于不同的版本,不同的操作 ...
- JavaScript 函数的两种声明方式
1.函数声明的方式 JavaScript声明函数有两种选择:函数声明法,表达式定义法. 函数声明法 function sum (num1 ,num2){ return num1+num2 } 表达式定 ...
- MySQL_02之增删改查、PHP数据库操作
1.数据操作: ①插入记录: 插入单条记录:INSERT tbl_name(字段名称,--) VALUES(字段值,--); 插入多条记录:INSERT tbl_name(字段名称,--) VAL ...
- 【深入浅出Linux网络编程】 "开篇 -- 知其然,知其所以然"
[深入浅出Linux网络编程]是一个连载博客,内容源于本人的工作经验,旨在给读者提供靠谱高效的学习途径,不必在零散的互联网资源中浪费精力,快速的掌握Linux网络编程. 连载包含4篇,会陆续编写发出, ...
- .Net 转战 Android 4.4 日常笔记(10)--ADT集成环境更新SDK
今天下载了一份原来来参考,却发现SDK版本偏低我没有安装 用SDK Manager却一直更新不了出现 Failed to fetch URL https://dl-ssl.google.com/and ...
- ECMAScript5之StrictMode
ECMAScript5引入一个严格模式的概念(Strict Mode). 它的作用就是不让Javascript的容错那么高,让我们对编写代码的规范要求高一点. 比如,当我们使用严格模式编写JavaSc ...
- php判断数据库是否连接成功的测试例子
php判断数据库是否连接成功的测试例子 如果出现数据库配置不正确的错误,请看php与mysql的配置教程: win7系统下如何配置php-Apache-mysql环境 http://www.cnblo ...