目录
九、页面实现
一、抽象工厂模式
提供了一个或一系列相互关联或依赖的对象接口。而且是所有工厂类设计模式最抽象和最实用的一种模式。
二、抽象工厂模式角色
1、抽象工厂角色,是核心。
2、具体工厂剧角色,在客户端下调用创建产品的实例。
3、抽象产品角色,所创建对象的父类,或这些类的共同接口。
4、具体产品,是一种实例。
对应着例子看一下会有比较深的理解。
三、代码实例一
绝味鸭脖近年来十分流行,可以说是很好吃了。希望五月份去北京比赛的时候可以吃到BeiJing Duck.......
假设绝味鸭脖在全国各地开设很多分店,并生产不同的鸭产品。但济宁和泰安人喜欢口味又不一样,所以不能生产同样口味的鸭产品。
第一个类:抽象工厂类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂_绝味
{
abstract class AbstractFactory
{
public abstract YaBo CreateYaBo();
public abstract YaTou CreateYaTou();
//这里的鸭头等就相当于下面的几个表
}
}
第二三个类:抽象产品类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂_绝味
{
abstract class YaBo
{
public abstract void show();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂_绝味
{
abstract class YaTou
{
public abstract void show();
}
}
第四-七个类:具体产品类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂_绝味
{
class JiNingYaBo : YaBo
{
public override void show()
{
Console.WriteLine("JiNingYaBo");
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂_绝味
{
class JiNingYaTou : YaTou
{
public override void show()
{
Console.WriteLine("JiNingYaTou");
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂_绝味
{
class TaiAnYabo : YaBo
{
public override void show()
{
Console.WriteLine("TaiAnYaBo");
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂_绝味
{
class TaiAnYaTou : YaTou
{
public override void show()
{
Console.WriteLine("TaiAnYaTou");
}
}
}
具体工厂类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂_绝味
{
class TaiAnFactory : AbstractFactory
{
public override YaBo CreateYaBo()
{
return new TaiAnYabo();
}
public override YaTou CreateYaTou()
{
return new TaiAnYaTou();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂_绝味
{
class JiNingFactory : AbstractFactory
{
public override YaBo CreateYaBo()
{
return new JiNingYaBo();
}
public override YaTou CreateYaTou()
{
return new JiNingYaTou();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂_绝味
{
class Program
{
static void Main(string[] args)
{
AbstractFactory jiNingFactory = new JiNingFactory();
YaBo jiNingYaBo = jiNingFactory.CreateYaBo();
jiNingYaBo.show();
YaTou jiNingYaTou = jiNingFactory.CreateYaTou();
jiNingYaTou.show();
}
}
}
四、代码实例二
连接数据库,这里先大体实现一下,等有时间改成数据库具体实现。
产品接口类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂模式_数据库
{
interface IUser
{
void Insert(User use);
void GetUser(string id);
}
}
工厂接口:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂模式_数据库
{
interface IFactory
{
IUser CreateUser();//定义方法,返回值类型都是IUser
}
}
具体工厂类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂模式_数据库
{
class AccessFactory : IFactory
{
public IUser CreateUser()
{
return new AccessUser();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂模式_数据库
{
class SqlserverFactory : IFactory
{
public IUser CreateUser()
{
return new SqlseverUser();
}
}
}
具体对象类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂模式_数据库
{
class SqlseverUser : IUser
{
public void GetUser(string id)
{
Console.WriteLine(id);
}
public void Insert(User use)
{
Console.WriteLine("sql");
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂模式_数据库
{
class Program
{
static void Main(string[] args)
{
User user = new User();
IFactory factory = new SqlserverFactory();
//改数据库-------
IUser iu = factory.CreateUser();
iu.Insert(user);
iu.GetUser("1");
}
}
}
五、数据库连接实现
就是把那个输出语句改成现在的连接数据库就好了!这里再吐槽一句网上了配置数据库、连接数据库方法真是不敢恭维,等有空写一下详细过程。
再用以前的模板方法模式,利用他进行数据库连接,以后有时间再整理一下。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System;
using MySql.Data;
using MySql.Data.MySqlClient;
namespace 抽象工厂_数据库
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
String connectionStr = "server=127.0.0.1;port=3306;user=root;password=sannian1; database=student;";
// server=127.0.0.1/localhost 代表本机,端口号port默认是3306可以不写
MySqlConnection conn = new MySqlConnection(connectionStr);
//
//构造函数
try
{
conn.Open();//打开通道,建立连接,可能出现异常,使用try catch语句
Console.WriteLine("已经建立连接");
//在这里使用代码对数据库进行增删查改
string id = "1";
MySqlCommand cmd = new MySqlCommand("Select* from user where id="+id, conn);
MySqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
string username1 = reader.GetString("id");
string pass = reader.GetString("pwd");
Console.WriteLine(username1 + "----" + pass);
}
reader.Close();
}
catch (MySqlException ex)
{
Console.WriteLine(ex.Message);
}
finally
{
conn.Close();
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
六、XML+反射+模板方法+抽象工厂实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂
{
interface IFactory
{
IUser CreateUser();
IDepartment CreateDepartment();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂
{
interface IUser
{
bool Insert(User user);
User GetUser(int id);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂
{
interface IDepartment
{
bool Insert(Department department);
Department GetDepartment(int deptno);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂
{
class SqlFactory : IFactory
{
public IDepartment CreateDepartment()
{
return new SqlDepartment();
}
public IUser CreateUser()
{
return new SqlUser();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂
{
class AccessFactory : IFactory
{
public IDepartment CreateDepartment()
{
return new AccessDepartment();
}
public IUser CreateUser()
{
return new AccessUser();
}
}
}
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂
{
class AccessUser : IUser
{
public User GetUser(int id)
{
string pwd = null;
AccessUtil accessUtil = new AccessUtil();
try
{
string CommandString = "select pwd from [User] where [id]=" + id;
OleDbDataAdapter dataAdapter = new OleDbDataAdapter(CommandString, (OleDbConnection)accessUtil.Connect());
DataSet dataSet = new DataSet();
dataAdapter.Fill(dataSet, "[User]");
DataTable dataTable = dataSet.Tables["[User]"];
foreach (DataRow dataRow in dataTable.Rows)
{
Console.WriteLine("[pwd]: " + dataRow["pwd"]);
pwd = (string)dataRow["pwd"];
}
}
catch(Exception e)
{
accessUtil.Free();
Console.WriteLine(e.Message);
}
return new User(id,pwd);
}
public bool Insert(User user)
{
string sql = "insert into [User]([id],[pwd]) values(";
sql += user.Id + ",";
sql += user.Pwd + ")";
int n = 0;
AccessUtil accessUtil = new AccessUtil();
try
{
OleDbCommand command = new OleDbCommand(sql, (OleDbConnection)accessUtil.Connect());
n = command.ExecuteNonQuery();
}
catch(Exception e)
{
Console.WriteLine(e.Message);
accessUtil.Free();
}
if (n == 1) return true;
return false;
}
}
}
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂
{
class AccessDepartment : IDepartment
{
public Department GetDepartment(int deptno)
{
AccessUtil accessUtil = new AccessUtil();
string deptname = null;
try
{
string CommandString = "select name from [Employ] where [deptno]=" + deptno;
OleDbDataAdapter dataAdapter = new OleDbDataAdapter(CommandString, (OleDbConnection)accessUtil.Connect());
DataSet dataSet = new DataSet();
dataAdapter.Fill(dataSet, "[Employ]");
DataTable dataTable = dataSet.Tables["[Employ]"];
foreach (DataRow dataRow in dataTable.Rows)
{
Console.WriteLine("[deptname]: " + dataRow["deptname"]);
deptname = (string)dataRow["deptname"];
}
}
catch(Exception e)
{
accessUtil.Free();
Console.WriteLine(e.Message);
}
return new Department(deptno, deptname);
}
public bool Insert(Department department)
{
AccessUtil accessUtil = new AccessUtil();
string sql = "insert into [Employ]([deptno],[deptname]) values(";
sql += department.Deptno+",";
sql += department.Deptname + ")";
int n = 0;
try
{
OleDbCommand command = new OleDbCommand(sql, (OleDbConnection)accessUtil.Connect());
n = command.ExecuteNonQuery();
}
catch(Exception e)
{
accessUtil.Free();
}
if (n == 1) return true;
return false;
}
}
}
using System;
using System.Collections.Generic;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂
{
class SqlUser : IUser
{
public User GetUser(int id)
{
SqlUtil sqlUtil = new SqlUtil();
string pwd = null;
try
{
MySqlConnection conn =(MySqlConnection)sqlUtil.Connect();
Console.WriteLine("已经建立连接");
MySqlCommand cmd = new MySqlCommand("Select * from Users where id=" + id, conn);
MySqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
string username1 = reader.GetString("id");
string pass = reader.GetString("pwd");
pwd = pass;
Console.WriteLine(username1 + "----" + pass);
}
reader.Close();
}
catch (MySqlException ex)
{
Console.WriteLine(ex.Message);
}
finally
{
sqlUtil.Free();
}
return new User(id,pwd);
}
public bool Insert(User user)
{
int con = 0;
SqlUtil sqlUtil = new SqlUtil();
try
{
MySqlConnection conn = (MySqlConnection)sqlUtil.Connect();
Console.WriteLine("已经建立连接");
string command = "insert into Users values(";
command += user.Id + ",";
command += user.Pwd + ")";
Console.WriteLine(command);
MySqlCommand mySqlCommand = new MySqlCommand(command,conn);
mySqlCommand.ExecuteNonQuery();
con = mySqlCommand.ExecuteNonQuery();
}
catch (MySqlException ex)
{
Console.WriteLine(ex.Message);
}
finally
{
sqlUtil.Free();
}
if(con!=0) return true;
return false;
}
}
}
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂
{
class SqlDepartment : IDepartment
{
public Department GetDepartment(int deptno)
{
SqlUtil sqlUtil = new SqlUtil();
string deptname = null;
try
{
MySqlConnection conn = (MySqlConnection)sqlUtil.Connect();
Console.WriteLine("已经建立连接");
MySqlCommand cmd = new MySqlCommand("Select * from [Employ] where [deptno]=" + deptno, conn);
MySqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
string pass = reader.GetString("[deptname]");
deptname = pass;
}
reader.Close();
}
catch (MySqlException ex)
{
Console.WriteLine(ex.Message);
}
finally
{
sqlUtil.Free();
}
return new Department(deptno, deptname);
}
public bool Insert(Department department)
{
int con = 0;
SqlUtil sqlUtil = new SqlUtil();
try
{
MySqlConnection conn = (MySqlConnection)sqlUtil.Connect();
Console.WriteLine("已经建立连接");
string command = "insert into [Employ] values(";
command += department .Deptno+ ",";
command += department.Deptname + ")";
Console.WriteLine(command);
MySqlCommand mySqlCommand = new MySqlCommand(command, conn);
mySqlCommand.ExecuteNonQuery();
con = mySqlCommand.ExecuteNonQuery();
}
catch (MySqlException ex)
{
Console.WriteLine(ex.Message);
}
finally
{
sqlUtil.Free();
}
if (con != 0) return true;
return false;
}
}
}
数据库连接模板
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂
{
abstract class DatabaseUtil
{
public abstract Object Connect();
public abstract void Free();
}
}
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂
{
class AccessUtil : DatabaseUtil
{
private string ConnenctString = "Provider=Microsoft.Jet.OLEDB.4.0 ;Data Source=D:\\User.mdb";
private string CommandString;
private DataSet dataSet = null;
OleDbConnection connection = null;
public override Object Connect()
{
OleDbConnection connection = new OleDbConnection(ConnenctString);
connection.Open();
return connection;
}
public override void Free()
{
if (connection != null) connection.Close();
}
}
}
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂
{
class SqlUtil : DatabaseUtil
{
private static String connectionStr = "server=127.0.0.1;port=3306;user=root;password=sannian1; database=student;";
private static MySqlConnection conn = new MySqlConnection(connectionStr);
public override Object Connect()
{
conn.Open();
return conn;
}
public override void Free()
{
if (conn != null) conn.Close();
}
}
}
两个表类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂
{
class User
{
private int id;
private string pwd;
public User(int id, string pwd)
{
this.Id = id;
this.Pwd = pwd;
}
public int Id { get => id; set => id = value; }
public string Pwd { get => pwd; set => pwd = value; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂
{
class Department
{
private int deptno;
private string deptname;
public Department(int deptno, string deptname)
{
this.Deptno = deptno;
this.Deptname = deptname;
}
public int Deptno { get => deptno; set => deptno = value; }
public string Deptname { get => deptname; set => deptname = value; }
}
}
环境类
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace 抽象工厂
{
class Database
{
private static readonly string db = ConfigurationManager.AppSettings["db"];
private static readonly string AssemblyName= "抽象工厂";
public IUser GetUser()
{
try
{
string className = AssemblyName + "." + db + "User";
return (IUser)Assembly.Load(AssemblyName).CreateInstance(className);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return null;
}
public IDepartment GetDepartment()
{
try
{
string className = AssemblyName + "." + db + "Department";
return (IDepartment)Assembly.Load(AssemblyName).CreateInstance(className);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return null;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace 抽象工厂
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
IFactory factory = new AccessFactory();
AccessUser accessUser = (AccessUser)factory.CreateUser();
accessUser.GetUser(1);
Console.WriteLine("---------");
Database database = new Database();
IUser user = database.GetUser();
user.GetUser(1);
user.Insert(new User(467, "656"));
Console.WriteLine("---------");
}
}
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<appSettings>
<add key="DB" value="SqlSever"/>
</appSettings>
</configuration>
七、对配置文件的更改
实现页面内选择数据库进行操作,就要用到配置文件的写入更新,有时间写一下页面。
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Configuration config = System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
//根据Key读取<add>元素的Value
string name = config.AppSettings.Settings["DB"].Value;
//写入<add>元素的Value
Console.WriteLine(name);
config.AppSettings.Settings["DB"].Value = "Access";
config.Save(ConfigurationSaveMode.Modified);
//刷新,否则程序读取的还是之前的值(可能已装入内存)
System.Configuration.ConfigurationManager.RefreshSection("appSettings");
User user = new User("10",466);
IUser iu = DataAccess.CreateUser();
iu.GetUser("1");
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
如果再想添加对一个表的管理,就要用再加:
一个IDepartment接口
一个SqlserverDepartment用户类
一个AccessDepartment用户类
这时还未违背开放-封闭原则。
在IFactory中,加入了 类型为IDepartment 的函数CreateDepartment函数,这时违背了开放-封闭原则。
----------------------------------------------------------------------
八、UML图
花了一小时画出来的.....................令人恶心这玩意,一个比一个难用。自动生成又加深不了理解,真的是恶心。