DesignMode这个系列是我准备记录下,我最近阅读的一本书–大话设计模式,会用到书里的实例,也会加入一些自己的体会。这一期是书的第一章,关于简单工厂设计模式,具体用一个计算器的实例来简单说明这种设计模式的好处。
开发软件Visual Studio2013,WPF开发。
打开VS新建项目,选择WPF应用,客户端代码肯定是有问题的,水平有限,高手忽略,主要分享的是后台的工厂模式的代码。
首先新建一个父类Operation.cs
public class Operation
{
private double _numberA = 0;
private double _numberB = 0;
public double NumberA
{
get { return _numberA; }
set { _numberA = value; }
}
public double NumberB
{
get { return _numberB; }
set { _numberB = value; }
}
public virtual double GetResult()//用于子类复写
{
double result = 0;
return result;
}
}
再新建四个子类继承自Operation,分别为OperationAdd.cs,OperationSub.cs,
OperationMul.cs,OperationDiv.cs
class OperationAdd:Operation
{
public override double GetResult()
{
double result = 0;
result = NumberA + NumberB;
return result;
}
}
class OperationDiv:Operation
{
public override double GetResult()
{
double result = 0;
if (NumberB == 0)
{
throw new Exception("除数不能为0");
}
result = NumberA/NumberB;
return result;
}
}
class OperationMul:Operation
{
public override double GetResult()
{
double result = 0;
result = NumberA*NumberB;
return result;
}
}
class OperationSub:Operation
{
public override double GetResult()
{
double result = 0;
result = NumberA - NumberB;
return result;
}
}
最后建立工厂类OperationFactory.cs,用来实例化对象,使用工厂模式可以分离内部计算逻辑和客户端的耦合,客户端界面与内部计算逻辑分开。
public class OperationFactory
{
public static Operation CreateOperation(string operate)
{
Operation oper = null;
switch (operate)
{
case "+":
oper = new OperationAdd();
break;
case "-":
oper = new OperationSub();
break;
case "*":
oper = new OperationMul();
break;
case "/":
oper = new OperationDiv();
break;
default:
throw new Exception("算法不存在");
break;
}
return oper;
}
}
客户端调用
Operation oper;
oper = OperationFactory.CreateOperation("+");
oper.NumberA = 1;
oper.NumberB = 2;
double result oper.GetResult();
工厂模式到就结束了,可以调到最后看下测试图。
客户端代码MainWindow.xaml.cs,如果不按错应该没问题,按错的话。。。下面的代码可以忽略。。。
public enum OperationType
{
Add,
Sub,
Mul,
Div
}
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public double numberA=0;
public double numberB=0;
public string operate="";
public OperationType OperationType = OperationType.Add;
private void Button1_Click(object sender, RoutedEventArgs e)
{
Label1.Content += Button1.Content.ToString();
}
private void Button2_Click(object sender, RoutedEventArgs e)
{
Label1.Content += Button2.Content.ToString();
}
private void Button3_Click(object sender, RoutedEventArgs e)
{
Label1.Content += Button3.Content.ToString();
}
private void Button4_Click(object sender, RoutedEventArgs e)
{
Label1.Content += Button4.Content.ToString();
}
private void Button5_Click(object sender, RoutedEventArgs e)
{
Label1.Content += Button5.Content.ToString();
}
private void Button6_Click(object sender, RoutedEventArgs e)
{
Label1.Content += Button6.Content.ToString();
}
private void Button7_Click(object sender, RoutedEventArgs e)
{
Label1.Content += Button7.Content.ToString();
}
private void Button8_Click(object sender, RoutedEventArgs e)
{
Label1.Content += Button8.Content.ToString();
}
private void Button9_Click(object sender, RoutedEventArgs e)
{
Label1.Content += Button9.Content.ToString();
}
private void Button0_Click(object sender, RoutedEventArgs e)
{
Label1.Content += Button0.Content.ToString();
}
private void ButtonPoint_Click(object sender, RoutedEventArgs e)
{
if (Label1.Content.ToString().Contains("."))
{
return;
}
else
{
Label1.Content += ButtonPoint.Content.ToString();
}
}
private void ButtonC_Click(object sender, RoutedEventArgs e)
{
Label1.Content = "";
numberA = 0;
numberB = 0;
operate = "";
}
private void ButtonAdd_Click(object sender, RoutedEventArgs e)
{
numberA = double.Parse(Label1.Content.ToString());
Label1.Content = "";
OperationType = OperationType.Add;
}
private void ButtonSub_Click(object sender, RoutedEventArgs e)
{
numberA = double.Parse(Label1.Content.ToString());
Label1.Content = "";
OperationType = OperationType.Sub;
}
private void ButtonMul_Click(object sender, RoutedEventArgs e)
{
numberA = double.Parse(Label1.Content.ToString());
Label1.Content = "";
OperationType = OperationType.Mul;
}
private void ButtonDiv_Click(object sender, RoutedEventArgs e)
{
numberA = double.Parse(Label1.Content.ToString());
Label1.Content = "";
OperationType = OperationType.Div;
}
private void ButtonResult_Click(object sender, RoutedEventArgs e)
{
numberB = double.Parse(Label1.Content.ToString());
Operation oper = null;
switch (OperationType)
{
case OperationType.Add:
oper = OperationFactory.CreateOperation("+");
break;
case OperationType.Sub:
oper = OperationFactory.CreateOperation("-");
break;
case OperationType.Mul:
oper = OperationFactory.CreateOperation("*");
break;
case OperationType.Div:
oper = OperationFactory.CreateOperation("/");
break;
}
oper.NumberA = this.numberA;
oper.NumberB = this.numberB;
double result = oper.GetResult();
Label1.Content = result;
}
}
MainWindow.xaml下放置这么多按钮。。
<Window x:Class="CalcApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="计算器" Height="400" Width="350">
<Grid Name="CalcGrid">
<Label Name="Label1" Content="" HorizontalAlignment="Left" Margin="10,30,0,0" VerticalAlignment="Top" Width="322" HorizontalContentAlignment="Right" BorderThickness="0"/>
<Button Name="Button1" Content="1" HorizontalAlignment="Left" Margin="62,120,0,0" VerticalAlignment="Top" Width="30" Height="30" Click="Button1_Click" />
<Button Name="Button2" Content="2" HorizontalAlignment="Left" Margin="102,120,0,0" VerticalAlignment="Top" Width="30" Height="30" Click="Button2_Click" />
<Button Name="Button3" Content="3" HorizontalAlignment="Left" Margin="142,120,0,0" VerticalAlignment="Top" Width="30" Height="30" Click="Button3_Click" />
<Button Name="Button4" Content="4" HorizontalAlignment="Left" Margin="62,160,0,0" VerticalAlignment="Top" Width="30" Height="30" Click="Button4_Click" />
<Button Name="Button5" Content="5" HorizontalAlignment="Left" Margin="102,160,0,0" VerticalAlignment="Top" Width="30" Height="30" Click="Button5_Click" />
<Button Name="Button6" Content="6" HorizontalAlignment="Left" Margin="142,160,0,0" VerticalAlignment="Top" Width="30" Height="30" Click="Button6_Click" />
<Button Name="Button7" Content="7" HorizontalAlignment="Left" Margin="62,200,0,0" VerticalAlignment="Top" Width="30" Height="30" Click="Button7_Click" />
<Button Name="Button8" Content="8" HorizontalAlignment="Left" Margin="102,200,0,0" VerticalAlignment="Top" Width="30" Height="30" Click="Button8_Click" />
<Button Name="Button9" Content="9" HorizontalAlignment="Left" Margin="142,200,0,0" VerticalAlignment="Top" Width="30" Height="30" Click="Button9_Click" />
<Button Name="Button0" Content="0" HorizontalAlignment="Left" Margin="62,240,0,0" VerticalAlignment="Top" Width="30" Height="30" Click="Button0_Click" />
<Button Name="ButtonPoint" Content="." HorizontalAlignment="Left" Margin="102,240,0,0" VerticalAlignment="Top" Width="30" Height="30" Click="ButtonPoint_Click" />
<Button Name="ButtonC" Content="C" HorizontalAlignment="Left" Margin="102,306,0,0" VerticalAlignment="Top" Width="30" Height="30" Click="ButtonC_Click" />
<Button Name="ButtonResult" Content="=" HorizontalAlignment="Left" Margin="142,306,0,0" VerticalAlignment="Top" Width="30" Height="30" Click="ButtonResult_Click" />
<Button Name="ButtonAdd" Content="+" HorizontalAlignment="Left" Margin="206,120,0,0" VerticalAlignment="Top" Width="30" Height="30" Click="ButtonAdd_Click" />
<Button Name="ButtonSub" Content="-" HorizontalAlignment="Left" Margin="206,160,0,0" VerticalAlignment="Top" Width="30" Height="30" Click="ButtonSub_Click" />
<Button Name="ButtonMul" Content="*" HorizontalAlignment="Left" Margin="206,200,0,0" VerticalAlignment="Top" Width="30" Height="30" Click="ButtonMul_Click" />
<Button Name="ButtonDiv" Content="/" HorizontalAlignment="Left" Margin="206,240,0,0" VerticalAlignment="Top" Width="30" Height="30" Click="ButtonDiv_Click" />
</Grid>
</Window>
下面是测试图:
如果要添加其他的方法,比如开根号,sin,cos等计算方法,只需要,新加一个类,并且在工厂模式中添加对象实例化的方法就行,基本与客户端分离。