.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)模式
上一篇的工厂方法模式引入了工厂等级结构,解决了在原来简单工厂模式中工厂类职责太重的原则,但是由于工厂方法模式的每个工厂只生产一类产品,可能会导致系统中存在大量的工厂类,从而增加系统开销.那么,我们应该 ...
随机推荐
- 登陆数据库,界面一直保持正在登陆的状态,oracle使用界面无法登陆
原因:关机时没有关闭oracle窗口. 导致在登陆数据库的时候,使用oracle的这个界面登陆时,界面一直保持''正在登陆''的状态,一旦点击就会卡住,使界面变得无法响应. 然后使用sqlplus仍然 ...
- docfx组件介绍--MarkdownLite
在docfx中,最重要的就是生成文档,把markdown文件(gfm语法)转换成html. 为了这一步,我们找了N个.net开源项目,发现要么是common markdown的,要么不容易扩展,没有一 ...
- “安装项目” Step By Step
目录 一 基本操作 二 定制安装对话框 三 安装程序类 四 总结 .NET程序集因为包含了元数据,所以程序集具有自描述性.多数程序自身包含了运行所需要的全部信息,这类程序集就是我们常说的“绿色软件”. ...
- Ubuntu 16 安装JDK1.8
检查是否JDK已被安装: 上图表示没有安装,创建文件夹: 下载JDK: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-dow ...
- Zookeeper API for JAVA实战与应用
package com.zookeeper.watcher; import java.util.List; import java.util.concurrent.CountDownLatch; im ...
- 跨域资源共享(CORS)在ASP.NET Web API中是如何实现的?
在<通过扩展让ASP.NET Web API支持W3C的CORS规范>中,我们通过自定义的HttpMessageHandler自行为ASP.NET Web API实现了针对CORS的支持, ...
- Xcode升级 Alcatraz 无法使用
Alcatraz 主要是可以管理xcode 插件 随着 Xcode 的更新 Alcatraz 有可能无法使用 以下是解决办法: 1,关闭Xcode 2,如果已经安装过 Alcatraz,先卸载掉,然后 ...
- MongoDB 创建 Database 和 Collection
在开始使用MongoDB(Version:3.2.9)之前,必须首先在MongoDB中创建 Database 和 Collection.Database是相互独立的,每个Database都有自己的Co ...
- Security7:View Usage
一,在Database level上,主要有 sys.database_principals, sys.database_permissions 和 sys.database_role_members ...
- AOE网的关键路径的计算
求关键路径,只需理解顶点(事件)和边(活动)各自的两个特征属性以及求法即可: Ø 先根据首结点的Ve(j)=0由前向后(正拓扑序列)计算各顶点的最早发生时间 Ø 再根据终结点的Vl(j)等于它的V ...