对于策略模式和工厂模式我可以说是还很迷糊的。我查了资料。有人这样区分它们,也举了很形象的例子,想想其实也是这样一个道理。
一般情况下,策略模式解决的是策略的切换与扩展,更简洁的说是定义策略族(我也有点儿不懂),分别封装起来,让他们之间可以相互替换,策略模式让策略的变化独立于使用策略的客户。可以应用的场景有优惠系统、工资计算系统等。而工厂模式主要解决的是资源的统一分发,将对象的创建完全独立出来,让对象的创建和具体的使用客户无关。主要应用在多数据库选择,类库文件加载等。
很明显的是策略模式是开放的,作为一个主体的我们的活动范围是全程的,大多数事情要你自己亲力亲为。
而工厂模式作是封闭的,作为主体的我们的活动范围是有限的,很多事情提前帮你做好了。我们便可以直接使用了。
这是这几天在错误中摸索,在资料中查询的结果。继续查找,继续理解。
就说我的这个计算器。试着选择用多态简单的工厂模式,这样就可以说客户可以直接运行,而不用再亲自进行一些不必要的过程。完善中,,,,
利用多态实现
Calculate计算类; public class Calculate { private double a;//第一个数 public double A//封装字段 { get { return a; } set { a = value; } } private double b;//第二个数字段封装 public double B { get { return b; } set { b = value; } } public double result; public virtual double Result()//利用多态实现简单工厂模式 { return result; } } public class Add : Calculate//派生加法类 { public override double Result()//重写基类中的方法,进行计算 { result = A + B; return result; } } public class Sub : Calculate { public override double Result() { result = A - B; return result; } } public class Mul : Calculate { public override double Result() { result = A * B; return result; } } public class Div : Calculate { public override double Result() { if (A == 0) { MessageBox.Show("分母不能为零"); } result = A / B; return result; } } public class Mod : Calculate { public override double Result() { if (A == 0) { MessageBox.Show("分母不能为零"); } result = A % B; return result; } } public class calculate//运算类型 { public static Calculate Cal(string type)//派生一个为Calculate类型的Cal { Calculate cal = null;switch (type) { case "+": cal = new Add(); //加法 break; case "-": cal = new Sub(); break; case "*": cal = new Mul(); break; case "/": cal = new Div(); break; case "%": cal = new Mod(); break; default: break; } return cal; } } }
数据库定义了一个Sqltest类
namespace WFCaclualtor { public class Sqltest { public string strCon = @"Data Source=.;Initial Catalog=stuDb;Integrated Security=True"; public SqlConnection sqlCon = new SqlConnection(); public SqlDataAdapter sda = new SqlDataAdapter(); public DataSet ds = new DataSet(); public DataTable dt = new DataTable(); public SqlDataReader sdr; public void dbcon() { try { sqlCon = new SqlConnection(strCon); } catch (Exception e) { MessageBox.Show("数据库连接不成功:" + e.ToString()); } } public void dbFill(string selstr) { dt.Clear(); sda = new SqlDataAdapter(selstr, strCon); sda.Fill(ds, "test"); dt = ds.Tables["test"]; } public void dbSelect(string showInfo) { sqlCon.Open(); SqlCommand sqlcmd = new SqlCommand(showInfo, sqlCon); sdr = sqlcmd.ExecuteReader(); } public void dbInsert(string insertInfo) { sqlCon.Open(); SqlCommand sqlcmd = new SqlCommand(insertInfo, sqlCon); try { sqlcmd.ExecuteNonQuery(); } catch (Exception e) { MessageBox.Show("数据插入失败" + e.ToString()); } sqlCon.Close(); } public void dbGridViewUpd() { SqlCommandBuilder scb = new SqlCommandBuilder(sda); DialogResult result; result = MessageBox.Show("确定保存修改过的数据吗?", "操作提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question); if (result == DialogResult.OK) { dt = ds.Tables["test"]; sda.Update(dt); dt.AcceptChanges(); } } public void dbUpdate(string updStr) { sqlCon.Open(); SqlCommand sqlcmd = new SqlCommand(updStr, sqlCon); try { sqlcmd.ExecuteNonQuery(); MessageBox.Show("数据修改成功!"); } catch (Exception e) { MessageBox.Show("数据库修改失败" + e.ToString()); } sqlCon.Close(); } public void dbDelete(string delStr) { sqlCon.Open(); SqlCommand sqlcmd = new SqlCommand(delStr, sqlCon); try { sqlcmd.ExecuteNonQuery(); // MessageBox.Show("数据删除成功!"); } catch (Exception e) { MessageBox.Show("数据删除失败" + e.ToString()); } sqlCon.Close(); } } }
Form1代码Window窗体
namespace WFCaclualtor { public partial class Form1 : Form { Sqltest db = new Sqltest();//-----实例数据库一个对象进行对数据库的操作 public static int question = 0; public static int right = 0; public static int fault = 0; public static int t = 0; public static int n = 0; public string path = "C: tf";//保存文件路径 public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { // TODO: 这行代码将数据加载到表“stuDbDataSet.test”中。您可以根据需要移动或删除它。 this.testTableAdapter.Fill(this.stuDbDataSet.test); // TODO: 这行代码将数据加载到表“stuDbDataSet.test”中。您可以根据需要移动或删除它。 // this.testTableAdapter.Fill(this.stuDbDataSet.test); label10.Visible = true; label12.Visible = true; decriptionbt.Visible = true; txtresult.Visible = false; saveBt.Visible = false; openbt.Visible = false; } private void time_Tick(object sender, EventArgs e) { txtresult.Visible = true; t = Convert.ToInt32(txtTime.Text); time.Interval = 1000; if (t <= 0) { time.Enabled = false; MessageBox.Show("时间到!"); Form2 frm2 = new Form2(); frm2.ShowDialog(); } t = t - 1; txtTime.Text = t.ToString(); } private void Starbut_Click(object sender, EventArgs e) { if (txtTime.Text == "") { MessageBox.Show("请输入计算时间"); } else { txtresult.Enabled = true; if (ComChoosetxt.Text == "txt文件") { time.Start(); string[] type = new string[100]; type = File.ReadAllLines("type.txt"); typ1.Text = type[n]; string[] one = new string[100]; one = File.ReadAllLines("one.txt"); txtone.Text = one[n]; string[] two = new string[100]; two = File.ReadAllLines("two.txt"); txttwo.Text = two[n]; n++; } else { MessageBox.Show("请选择做题方式!"); } } } //——————————————————————开始答题 private void txtresult_KeyDown(object sender, KeyEventArgs e) { string typ = typ1.Text.Trim();//调用类成员 // 多态 GetCalculate cal; cal = InCalculate.Cal(typ) cal.A = Convert.ToDouble(txtone.Text.Trim()); cal.B = Convert.ToDouble(txttwo.Text.Trim()); double result= cal.Result();
if (e.KeyCode == Keys.Enter) { if (txtresult.Text == result.ToString())//txtresult="7" result=0? { MessageBox.Show("计算正确"); right++; LaRigth.Visible = true; RicRight.Visible = true; // RicFault.Text += db.dt.Rows[0][0].ToString() + db.dt.Rows[0][1].ToString() + db.dt.Rows[0][2].ToString() + " " + " "; RicRight.Text += txtone.Text + typ1.Text + txttwo.Text + label3.Text + txtresult.Text + " " + "✔☺" + " "; } else { MessageBox.Show("计算错误继续努力"); fault++; RicFault.Visible = true; LaFault.Visible = true; //RicFault.Text += db.dt.Rows[0][0].ToString() + db.dt.Rows[0][1].ToString() + db.dt.Rows[0][2].ToString() + " " + " "; RicFault.Text += txtone.Text + typ1.Text + txttwo.Text + label3.Text + txtresult.Text + " " + "✘☹" + " "; } question++; txtone.Clear(); typ1.Clear(); txttwo.Clear(); txtresult.Clear(); } }//---------------------------------判断计算情况 private void removebt_Click(object sender, EventArgs e) { switch (ComChoosetxt.Text) { case "SQL数据库": db.dbcon(); string sqlDeltest = "delete from test where ID='" + ComtestID.Text.ToString().Trim() + "'"; txtone.Clear(); typ1.Clear(); txttwo.Clear(); MessageBox.Show("删除成功"); db.dbDelete(sqlDeltest); break; case "txt文件": File.WriteAllText("one.txt", string.Empty); File.WriteAllText("two.txt", string.Empty); File.WriteAllText("type.txt", string.Empty); MessageBox.Show("题目已清空请重新出题"); richTextBox1.Clear(); break; default: break; } } //----------------------------------------删除题目 private void Nexttest_Click(object sender, EventArgs e) { switch (ComChoosetxt.Text) { case "txt文件": FiletestMethod(); break; case "SQL数据库": db.dbcon(); //向数据库中输入数据 string strIntest = "insert into test(ID,one,type,two)values('" + ComtestID.Text + "','" + txtone.Text + "','" + typ1.Text + "','" + txttwo.Text + "')"; txtone.Clear(); typ1.Clear(); txttwo.Clear(); MessageBox.Show("请出下一题"); db.dbInsert(strIntest); break; default: break; } richTextBox1.Visible = true; txtone.Clear(); typ1.Clear(); txttwo.Clear(); } //---------------------------------------出题 private void saveBt_Click(object sender, EventArgs e) { //----------------定义一个用来保存文件的对话框 SaveFileDialog TxtSaveDialog = new SaveFileDialog(); //--------------设置保存文件的过滤参数 TxtSaveDialog.Filter = "RTF文件(*.RTF)|*.RTF"; //--------------------对于文件是否存在进行判断,另外给出相应的解决措施 if (File.Exists(path)) { this.richTextBox1.LoadFile(path, RichTextBoxStreamType.RichText); MessageBox.Show("保存成功", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); this.richTextBox1.Clear(); } else { if (TxtSaveDialog.ShowDialog() == DialogResult.OK) { this.richTextBox1.SaveFile(TxtSaveDialog.FileName, RichTextBoxStreamType.RichText); MessageBox.Show("保存成功", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); this.richTextBox1.Clear(); } } }//保存文件中的题目 private void openbt_Click(object sender, EventArgs e) { //------------------------声明一个打开对话框 OpenFileDialog txtOpen = new OpenFileDialog(); txtOpen.Filter = "RTF文件(*.RTF)|*.RTF"; if (txtOpen.ShowDialog() == DialogResult.OK) { //打开保存文件的路径 path = txtOpen.FileName; this.richTextBox1.LoadFile(txtOpen.FileName, RichTextBoxStreamType.RichText); saveBt.Enabled = false; openbt.Enabled = false; MessageBox.Show("读取成功", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); } }//打开文件中的题目 private void ComtestID_SelectedIndexChanged_1(object sender, EventArgs e) { if (txtTime.Text == "") { MessageBox.Show("请输入计算时间"); } else { time.Start(); db.dbcon(); string sqlSetest = "select one,type,two from test where ID='" + ComtestID.Text.ToString().Trim() + "'"; db.dbSelect(sqlSetest); while (db.sdr.Read()) { txtone.Text = db.sdr["one"].ToString().Trim(); typ1.Text = db.sdr["type"].ToString().Trim(); txttwo.Text = db.sdr["two"].ToString().Trim(); } } }////------------------通过选择题目将题从数据中导入到文本框中 private void ComChoosetxt_SelectedIndexChanged(object sender, EventArgs e) { switch (ComChoosetxt.Text) { case "SQL数据库": label4.Visible = true; label7.Visible = true; ComtestID.Visible = true; Nexttest.Visible = true; openbt.Visible = false; saveBt.Visible = false; Starbut.Enabled = false; break; case "txt文件": label4.Visible = false; label7.Visible = false; ComtestID.Visible = false; Nexttest.Visible = true; openbt.Visible = true; saveBt.Visible = true; Starbut.Enabled = true; break; default: ComChoosetxt.Text = "请选择存题方式"; break; } }//选择计算方式 private void FiletestMethod() { txtresult.Enabled = false; StreamWriter one = File.AppendText("one.txt"); one.WriteLine(txtone.Text); one.Close(); StreamWriter ty1 = File.AppendText("type.txt"); ty1.WriteLine(typ1.Text); ty1.Close(); StreamWriter two = File.AppendText("two.txt"); two.WriteLine(txttwo.Text); two.Close(); //type = typ1.Text; richTextBox1.Text += txtone.Text + typ1.Text + txttwo.Text + label3.Text + "" + " "; txtone.Clear(); typ1.Clear(); txttwo.Clear(); } //自定义方法将将题目利用File对象写入文件中 private void Overbtn_Click(object sender, EventArgs e) { Form2 fm2 = new Form2(); fm2.ShowDialog(); }//-----------------------------------退出程序,计算结束 private void Closebt_Click(object sender, EventArgs e) { MessageBox.Show("谢谢使用<☺>"); Application.Exit(); }//中断或者停止答题,给出计算情况 private void decriptionbt_Click(object sender, EventArgs e) { label10.Visible = false; decriptionbt.Visible = false; label12.Visible = false; } }
图示:
WPF应用程序
WPF代码
/// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { public static int question = 0; public static int right = 0; public static int t; public static string type = ""; public static double result = 0; public int n = 0;//文件中的数据 public MainWindow() { InitializeComponent(); } private void txtresult_KeyDown(object sender, KeyEventArgs e) {
Calculate cal=null;string typ = typ1.Text.ToString();//调用类成员
cal = calculate.Cal(typ);
cal.A = Convert.ToDouble(txtone.Text);
cal.B= Convert.ToDouble(txttwo.Text);
string result = Convert.ToString(cal.Result());
if (e.Key==Key.Enter) { if (txtresult.Text == cal.result.ToString()) { righttxt.Visibility = Visibility.Visible; righttxt.Text += txtone.Text + typ.Text + txttwo.Text +Li.Content+ txtresult.Text + "正确√" +""+ " "; MessageBox.Show("回答正确"); txtone.Text = ""; txttwo.Text = ""; //txtthree.Text = ""; txtresult.Text = ""; typ.Text = ""; //typ2.Text = ""; question++; } else { MessageBox.Show("回答错误"); faulttxt.Visibility = Visibility.Visible; faulttxt.Text += txtone.Text + typ.Text + txttwo.Text + Li.Content + txtresult.Text + "错误×" + "" + " "; txtone.Text = ""; txttwo.Text = ""; //txtthree.Text = ""; txtresult.Text = ""; typ.Text = ""; //typ2.Text = ""; } question++; } } } }
截图
ASP.net
Calculate计算类;
public class Calculate //抽象类 Calculate { private double a;//第一个数 public double A//封装字段 { get { return a; } set { a = value; } } private double b;//第二个数字段封装 public double B { get { return b; } set { b = value; } } public double result; public virtual double Result() { return result; } } public class Add : Calculate { public override double Result() { result = A + B; return result; } } public class Sub : Calculate { public override double Result() { result = A - B; return result; } } public class Mul : Calculate { public override double Result() { result = A * B; return result; } } public class Div : Calculate { public override double Result() { if (A == 0) { MessageBox.Show("分母不能为零"); } result = A / B; return result; } } public class Mod : Calculate { public override double Result() { if (A == 0) { MessageBox.Show("分母不能为零"); } result = A % B; return result; } } public class calculate { public static Calculate Cal(string type) { Calculate cal =null; switch (type) { case "+": cal = new Add(); //加法 break; case "-": cal = new Sub(); break; case "*": cal = new Mul(); break; case "/": cal = new Div(); break; case "%": cal = new Mod(); break; default: break; } return cal; } } }
后台代码
protected void calcilate_Click(object sender, EventArgs e) { Calculate cal = null;string typ = DDLtype.SelectedValue.ToString();//调用类成员 cal = calculate.Cal(typ);//运算类型 cal.A = Convert.ToDouble(one.Text);//第一个数 cal.B = Convert.ToDouble(two.Text);//第二个数 string answer = Convert.ToString(cal.Result());//答案 if (result.Text == answer.ToString())//判断计算结果 { Response.Write("<script>alert('回答正确')</script>"); Panel1.GroupingText = one.Text + DDLtype.SelectedValue + two.Text + Label1.Text + result.Text;//将题放入panel中 one.Text = ""; two.Text = ""; result.Text = ""; DDLtype.SelectedValue = "请选择计算类型"; } else { Response.Write("<script>alert('回答错误')</script>"); one.Text = " "; two.Text = " "; result.Text = " "; DDLtype.SelectedValue = "请选择计算类型"; } Panel1.Visible = true; }
截图