概述
抽象工廠模式(Abstract Factory)是所有形態(tài)的工廠模式中最為抽象和最具一般性的一種形態(tài)熬词。抽象工廠模式是指當(dāng)有多個抽象角色時挽懦,使用的一種工廠模式。抽象工廠模式可以向客戶端提供一個接口,使客戶端在不必指定產(chǎn)品的具體的情況下罪帖,創(chuàng)建多個產(chǎn)品族中的產(chǎn)品對象躁劣。
定義
抽象工廠模式(Abstract Factory)迫吐,提供一個創(chuàng)建一系列相關(guān)或相互依賴對象的接口,而無需指定它們具體的類账忘。
UML圖解
AbstractFactory:聲明一個創(chuàng)建抽象產(chǎn)品對象的操作接口
ConcreteFactory:實(shí)現(xiàn)創(chuàng)建具體產(chǎn)品對象的操作
AbstractProduct:聲明一類產(chǎn)品對象接口
-
Product
定義一個被相應(yīng)具體工廠創(chuàng)建的產(chǎn)品對象
實(shí)現(xiàn)AbstractProduct接口
Client:使用AbstractFactory和AbstractProduct類聲明的接口
在抽象工廠模式中志膀,產(chǎn)品的創(chuàng)建由ConcreteFactory來完成,從結(jié)構(gòu)圖中可以看出鳖擒,抽象工廠模式的ConcreteFactory不是負(fù)責(zé)一種具體Product的創(chuàng)建溉浙,而是負(fù)責(zé)一個Product族的創(chuàng)建。
實(shí)現(xiàn)
說明:
1.本次實(shí)現(xiàn)以博客系統(tǒng)為例蒋荚,抽取其中的用戶和文章兩個對象進(jìn)行說明戳稽。
2.采用三層架構(gòu),為了省事圆裕,去掉了業(yè)務(wù)邏輯層(BLL)广鳍,希望理解。
示例項目結(jié)構(gòu)圖
示例項目類圖
- Blog.Models:模型層
- Blog.IDAL:數(shù)據(jù)訪問層接口(一類產(chǎn)品對象接口[AbstractProduct])
- Blog.DAL:數(shù)據(jù)訪問層分類實(shí)現(xiàn)(抽象產(chǎn)品具體分類實(shí)現(xiàn))
- MsSql:MsSql實(shí)現(xiàn)(抽象產(chǎn)品具體分類實(shí)現(xiàn)[ProductA1吓妆,ProductA2])
- MySql:MySql實(shí)現(xiàn)(抽象產(chǎn)品具體分類實(shí)現(xiàn)[ProductB1赊时,ProductB2])
- Blog.Factory:抽象工廠層
- lFactory:抽象工廠接口([AbstractFactory])
- MsSqlFactory:MsSql具體工廠(創(chuàng)建具體產(chǎn)品對象的操作[ConcreteFactory1])
- MySqlFactory:MySql具體工廠(創(chuàng)建具體產(chǎn)品對象的操作[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; }
}
}
數(shù)據(jù)訪問層接口(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);
}
}
數(shù)據(jù)訪問層分類具體實(shí)現(xiàn)(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();
}
}
}
調(diào)用(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();
}
}
}
優(yōu)點(diǎn):
1、封裝性行拢,每個產(chǎn)品的實(shí)現(xiàn)類不是高層模塊要關(guān)心的祖秒。
2、產(chǎn)品族內(nèi)的約束為非公開狀態(tài)舟奠。
缺點(diǎn):
產(chǎn)品族擴(kuò)展非常困難竭缝。
使用場景:
一個對象族或是一組沒有任何關(guān)系的對象都有相同的約束,則可以使用抽象工廠模式沼瘫。
注意事項:
產(chǎn)品族擴(kuò)展困難抬纸,產(chǎn)品等級非常容易擴(kuò)展,也就是橫向擴(kuò)展容易耿戚,縱向擴(kuò)展困難湿故。
本文采用知識共享署名-相同方式共享 4.0 國際許可協(xié)議進(jìn)行許可。
基于簡書上的作品創(chuàng)作膜蛔。 可轉(zhuǎn)載坛猪、引用,但需經(jīng)本人同意后署名作者且注明文章出處皂股,并以相同方式共享墅茉。