火车售票系统(设计模式分析)
我们使用了visual studio开发工具,利用winform平台实现了客户端的功能,其中有管理员账号的注册与登录,管理员进行增加车次与取消车次的操作。
一、设计模式定义
设计模式一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结,是一种用于对软件系统中不断重现的设计问题的解决方案进行文档化的技术,是一种共享专家设计经验的技术。设计模式的目的是为了可重用代码、让代码更容易被他人理解、提高代码可靠性。
二、简单工厂模式的运用
简单工厂模式 :定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。
在本实验中,实现管理员增加车次与取消车次,定义抽象产品类Operation,其中声明公共业务方法和抽象业务方法。定义具体产品类AddTrainMethod(增加车次),继承自Operation类,实现业务方法。定义具体产品类DeleteTrainMethod(取消车次)继承自Operation类,实现业务方法。
定义工厂类Factory,封装GetOperation方法,根据传入的参数不同创建、返回不同的具体产品类的对象。当参数为“ADD”,创建并返回AddTrainMethod对象,当参数为“DELETE”,创建并返回DeleteTrainMethod对象。
Operation.cs
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TrainTicketSystem
{
abstract class Operation
{
public void MethodSame()//公共业务方法
{
}
public abstract void MethodDiff();
}
class AddTrainMethod : Operation
{
public override void MethodDiff()
{
AddTrainForm add = new AddTrainForm();
add.ShowDialog();
}
}
class DeleteTrainMethod : Operation
{
MySqlConnection conn = null;
public override void MethodDiff()
{
try
{
MySqlConnection myconn = new MySqlConnection(CurrentNeed.Conne);
myconn.Open();
MySqlCommand mycom = new MySqlCommand("delete from train where ID = '" + CurrentNeed.ID + "'", myconn);
mycom.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show("查询错误!" + ex.Message);
}
finally
{
if (conn != null)
{
conn.Close();
}
}
}
}
class Factory
{
public static Operation GetOperation(string g)
{
Operation operation = null;
if (g.Equals("ADD"))
{
operation = new AddTrainMethod();
}
else if (g.Equals("DELETE"))
{
operation = new DeleteTrainMethod();
}
return operation;
}
}
}
三、观察者模式的运用
观察者模式:定义对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象都得到通知并被自动更新。
在本实验中,实现了增加车次和删除车次后菜单界面更新操作后的结果。当增加车次或者删除车次后,显示表得到通知并自动更新。
Refresh.cs
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TrainTicketSystem
{
class Refersh
{
public static DataSet newDataSet()//观察者模式的被通知者
{
MySqlConnection conn = null;
DataSet ds;
try
{
conn = new MySqlConnection(CurrentNeed.Conne);
string sql = "select * from train";
MySqlDataAdapter sda = new MySqlDataAdapter(sql, conn);
conn.Open();
ds = new DataSet();
sda.Fill(ds);
return ds;
}
catch (Exception ex)
{
MessageBox.Show("查询错误!" + ex.Message);
return null;
}
finally
{
if (conn != null)
{
conn.Close();
}
}
}
}
}
四、代码实现
1. 用户登录界面
登录界面
Login.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace TrainTicketSystem
{
public partial class Login : Form
{
public Login()
{
InitializeComponent();
CurrentNeed.Conne = "Data Source='localhost';Initial Catalog='flight_system';User Id = 'root';Password ='123456';charset=utf8;charset='utf8'; pooling=true;";
}
private void button1_Click(object sender, EventArgs e)//登录
{
CurrentNeed.Conne = "Data Source='localhost';Initial Catalog='flight_system';User Id = 'root';Password ='123456';charset=utf8;charset='utf8'; pooling=true;";
Account account = new Account();
if (PasswordText.Text == string.Empty || AccountText.Text == string.Empty)
{
MessageBox.Show("请输入账号或密码!", "提示");
}
else
{
if (account.IsAccountCorrect(int.Parse(AccountText.Text), PasswordText.Text))
{
CurrentNeed.UserAccount = int.Parse(AccountText.Text);
Menu MainMenuForm = new Menu();
this.Hide();
MainMenuForm.ShowDialog();
Application.ExitThread();
}
else
{
MessageBox.Show("账号或密码输入错误", "提示");
PasswordText.Clear();
AccountText.Clear();
}
}
}
private void button2_Click(object sender, EventArgs e)//注册
{
Register RegisterForm = new Register();
this.Hide();
RegisterForm.ShowDialog();
Application.ExitThread();
}
}
}
2. 用户注册界面
注册界面
已注册账号再次注册提示重复
成功创建新的账号
Register.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace TrainTicketSystem
{
public partial class Register : Form
{
public Register()
{
InitializeComponent();
}
private void button2_Click(object sender, EventArgs e)//返回登录
{
Login LoginForm = new Login();
this.Hide();
LoginForm.ShowDialog();
Application.ExitThread();
}
private void button1_Click(object sender, EventArgs e)//确定注册
{
if (tbAccount.Text == string.Empty || tbPassword.Text == string.Empty)
{
MessageBox.Show("请输入相应内容!", "提示");
tbAccount.Clear();
tbPassword.Clear();
tbConfirm.Clear();
}
else
{
Account account = new Account();
if (!account.IsAccountLegal(int.Parse(tbAccount.Text)))
{
MessageBox.Show("该账号重复!", "提示");
tbAccount.Clear();
tbPassword.Clear();
tbConfirm.Clear();
}
else
{
if (tbPassword.Text == tbConfirm.Text)
{
account.CreateAccount(int.Parse(tbAccount.Text), tbPassword.Text);
MessageBox.Show("您创建了一个新账户!", "创建成功");
Login LoginUIForm = new Login();
this.Hide();
LoginUIForm.ShowDialog();
Application.ExitThread();
}
else
{
MessageBox.Show("密码输入不一致!", "创建失败");
tbAccount.Clear();
tbConfirm.Clear();
tbPassword.Clear();
}
}
}
}
}
}
3. 菜单界面
Menu.cs
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TrainTicketSystem
{
public partial class Menu : Form
{
public Menu()
{
InitializeComponent();
RefershView(Refersh.newDataSet());
}
MySqlConnection conn = null;
string connStr = CurrentNeed.Conne;
private void button1_Click(object sender, EventArgs e)//添加
{
Operation op = Factory.GetOperation("ADD");
op.MethodDiff();
RefershView(Refersh.newDataSet());
}
public void RefershView(DataSet ds)//显示表
{
dataGridView1.DataSource = ds.Tables[0];
dataGridView1.Columns[0].HeaderText = "序号";
dataGridView1.Columns[1].HeaderText = "火车号";
dataGridView1.Columns[2].HeaderText = "始发站";
dataGridView1.Columns[3].HeaderText = "目的站";
dataGridView1.Columns[4].HeaderText = "发车时间";
dataGridView1.Columns[5].HeaderText = "到达时间";
dataGridView1.Columns[6].HeaderText = "车票数量";
dataGridView1.Columns[7].HeaderText = "车票价格";
dataGridView1.Columns[0].Visible = false;
}
private void button2_Click(object sender, EventArgs e)//删除
{
if (dataGridView1.DataSource != null)
{
if (MessageBox.Show("确认删除?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
{
int ind = dataGridView1.SelectedRows[0].Index;
DataGridViewRow row = dataGridView1.Rows[ind];
CurrentNeed.ID = Convert.ToInt32(row.Cells[0].Value);
Operation op = Factory.GetOperation("DELETE");
op.MethodDiff();
RefershView(Refersh.newDataSet());
}
}
}
}
4. 增加车次与取消车次
- 增加车次
增加车次界面
添加成功
AddTrainForm.cs
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TrainTicketSystem
{
public partial class AddTrainForm : Form
{
MySqlConnection connection;
public AddTrainForm()
{
string ConStr = CurrentNeed.Conne;
connection = new MySqlConnection(ConStr);
connection.Open();
Console.WriteLine("Connect!");
InitializeComponent();
}
//生产一个列车
private Train CreateNewTrain()
{
try
{
Train train = new Train();
train.TrainID = int.Parse(trainIDBox.Text);
train.TicketNum = int.Parse(NumBox.Text);
train.StartStation = startStationBox.Text;
train.ArriveStation = endStationBox.Text;
train.StartTime = startTimePicker.Value;
train.ArriveTime = endTimePicker.Value;
train.TicketPrice = int.Parse(PriceBox.Text);
return train;
}
catch(Exception e)
{
Console.WriteLine(e.Message);
return null;
}
}
//判断ID合法性
public bool IsTrainIDLegal(int id)
{
try
{
string sql = "select TrainID from train;";
MySqlCommand command = new MySqlCommand(sql, connection);
MySqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
if (id.ToString() == reader.GetString(0))
{
reader.Close();
return false;
}
}
reader.Close();
return true;
}
catch(Exception e)
{
Console.WriteLine(e.Message );
return false;
}
}
private void okButton_Click(object sender, EventArgs e)
{
if(startTimePicker.Value > endTimePicker.Value)
{
tiplb.Text = "时间错误!";
return;
}
if(startStationBox.Text == endStationBox.Text)
{
tiplb.Text = "站点错误!";
return;
}
int id = int.Parse(trainIDBox.Text);
if (!IsTrainIDLegal(id))
tiplb.Text = "该id已存在!";
try
{
Train train = CreateNewTrain();
if (train != null)
train.AddNewTrain();
tiplb.Text = "添加成功!";
}
catch
{
tiplb.Text += " 输入不合法!";
Console.WriteLine("添加失败!");
}
}
private void button1_Click(object sender, EventArgs e)
{
this.Hide();
this.Dispose();
}
}
}
- 取消车次
选择要删除的车次,点击删除按钮,取消车次
删除成功后菜单界面更新
5. Ticket类
Ticket.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TrainTicketSystem
{
class Ticket
{
private int trainID;
private int ticketID;
public int TrainID
{
get
{
return trainID;
}
set
{
trainID = value;
}
}
public int TicketID
{
get
{
return ticketID;
}
set
{
ticketID = value;
}
}
}
}
6. TicketManager类
TicketManager.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TrainTicketSystem
{
class TicketManager:Account
{
public void AddTrain()
{
Operation op;
op = Factory.GetOperation("ADD");
op.MethodDiff();
op.MethodSame();
}
public void DeleteTrain()
{
Operation op;
op = Factory.GetOperation("DELETE");
op.MethodDiff();
op.MethodSame();
}
}
}
7. Train类
Train.cs
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TrainTicketSystem
{
class Train
{
private int trainID;
private int ticketPrice;
private string startStation;
private string arriveStation;
private DateTime startTime;
private DateTime arriveTime;
private int ticketNum;
MySqlConnection Conn;
public void DatabaseConnection()
{
string ConStr = CurrentNeed.Conne;
Conn = new MySqlConnection(ConStr);
Conn.Open();
Console.WriteLine("Connect!");
}
public int TrainID
{
get
{
return trainID;
}
set
{
trainID = value;
}
}
public string StartStation
{
get
{
return startStation;
}
set
{
startStation = value;
}
}
public int TicketPrice
{
get
{
return ticketPrice;
}
set
{
ticketPrice = value;
}
}
public string ArriveStation
{
get
{
return arriveStation;
}
set
{
arriveStation = value;
}
}
public DateTime StartTime
{
get
{
return startTime;
}
set
{
startTime = value;
}
}
public DateTime ArriveTime
{
get
{
return arriveTime;
}
set
{
arriveTime = value;
}
}
public int TicketNum
{
get
{
return ticketNum;
}
set
{
ticketNum = value;
}
}
public void AddNewTrain()//创建新列车
{
DatabaseConnection();
try
{
string sql = "insert into train(TrainID ,StartStation, EndStation, StartTime, EndTime, Num, TicketPrice) values('" + TrainID + "','" + StartStation + "','" + ArriveStation + "','" + StartTime + "','" + ArriveTime + "','" + TicketNum + "','" + TicketPrice + "')";
MySqlCommand command = new MySqlCommand(sql, Conn);
command.ExecuteNonQuery();
}
catch (Exception e)
{
Console.WriteLine("添加列车失败: " + e.Message);
}
}
}
}