综合实战:超市收银系统设计模式
分析系统需求
超市提供的商品:笔记本电脑、手机、酱油、香蕉
商品在超市里面应该有:价格、数量、编号
这样就能抽象出来一个父类(ProductFather),包含价格(Price)、数量(Count)、编号(ID)ide
若是东西不够卖了,须要到仓库拿货物
仓库须要的功能:存储货物、提货、进货函数
超市卖东西时候须要一个收银的功能ui
抽象出一个商品的父类this
class ProductFather { public decimal Price { get; set; } public double Count { get; set; } public string ID { get; set; } public ProductFather(string id, decimal price, double count) { this.ID = id; this.Price = price; this.Count = count; } }
分别建立商品类继承于父类spa
class ShouJi:ProductFather { public ShouJi(string id, decimal price, double count) : base(id, price, count) { } }
建立仓库类设计
class CangKu
{
//1.存储货物
//1.1 list至关于仓库,List<ProductFather>添加数据的集合,至关于将货架放到仓库,从而分门别类
List<List<ProductFather>> list = new List<List<ProductFather>>();code
/// <summary> /// 想用户展现货物 /// </summary> public void ShowPros() { foreach (var item in list) { Console.WriteLine("仓库有:" + item[0].Name + "," + "\t" + "有" + item.Count + "个," + "\t" + "每一个" + item[0].Price + "元。"); } } /// <summary> /// 建立仓库对象时,向仓库中添加货架 /// </summary> //list[0] 存电脑 list[1]存手机 list[2]存酱油 list[3]存香蕉,这时候若是多,就能经过循环来完成 public CangKu() { list.Add(new List<ProductFather>()); list.Add(new List<ProductFather>()); list.Add(new List<ProductFather>()); list.Add(new List<ProductFather>()); } /// <summary> /// 进货 /// </summary> /// <param name="strType">货物的类型</param> /// <param name="count">货物的数量</param> public void GetPros(string strType,int count) { for (int i = 0; i < count; i++) { switch (strType) { case "NoteBook": list[0].Add(new NoteBook(Guid.NewGuid().ToString(), 5000, "笔记本电脑")); break; case "ShouJi":list[1].Add(new ShouJi(Guid.NewGuid().ToString(), 3000, "手机")); break; case "JiangYou":list[2].Add(new JiangYou(Guid.NewGuid().ToString(), 10, "酱油")); break; case "Banana":list[3].Add(new Banana(Guid.NewGuid().ToString(), 20, "香蕉")); break; } } } /// <summary> /// 取货 /// </summary> /// <param name="strType">货物的类型</param> /// <param name="count">货物的数量</param> //货物取出后,须要放哪?并且有可能会拿不少个因此返回ProductFather[] public ProductFather[] QuPros(string strType, int count) { ProductFather[] pros = new ProductFather[count]; for (int i = 0; i < count; i++) { switch (strType) { case "NoteBook": if (list[0].Count == 0) { Console.WriteLine("没有电脑了!"); } else { pros[i] = list[0][0]; list[0].RemoveAt(0); } break; case "ShouJi": if (list[1].Count == 0) { Console.WriteLine("没有手机了!"); } else { pros[i] = list[1][0]; list[1].RemoveAt(0); } break; case "JiangYou": if (list[2].Count == 0) { Console.WriteLine("没有酱油了!"); } else { pros[i] = list[2][0]; list[2].RemoveAt(0); } break; case "Banana": if (list[3].Count == 0) { Console.WriteLine("没有酱油了!"); } else { pros[i] = list[3][0]; list[3].RemoveAt(0); } break; } } return pros; } }
超市收银系统续
建立超市类orm
namespace 超市收银系统 { class SuperMarket { ////当用户进入超市后,仓库应该有东西,可是作完仓库类后依然没有货,建立仓库对象经过构造函数给予仓库货 CangKu ck = new CangKu(); /// <summary> /// 建立超市对象的时候,给仓库的货架上导入货物 /// </summary> public SuperMarket() { ck.GetPros("ShouJi", 1000); ck.GetPros("NoteBook", 1000); ck.GetPros("JiangYou", 1000); ck.GetPros("banana", 1000); } /// <summary> /// 跟客户交互的过程(问客户买什么) /// </summary> public void AskBuying() { Console.WriteLine("欢迎光临,请问您须要些什么"); Console.WriteLine("咱们这里有笔记本电脑(NoteBook)、手机(ShouJi)、酱油(JiangYou)、香蕉(Banana)"); string strType = Console.ReadLine(); Console.WriteLine("您须要多少?"); int count = Convert.ToInt32(Console.ReadLine()); //去仓库取货 ProductFather[] pros = ck.QuPros(strType, count); //取货后,计算价钱,写一个方法,计算总价钱 double realMoney = GetMoney(pros); Console.WriteLine("您购买的商品,总价是{0}元", realMoney); //打折方式 Console.WriteLine("您购买的商品,总价是{0}元", realMoney); Console.WriteLine("请选择你的打折方式 1--不打折 2--打九折 3--打85折 4--买300送50 5--买500送100"); string input = Console.ReadLine(); } /// <summary> /// 根据用户买的货物计算总价钱 /// </summary> /// <param name="pros">用户购买的货物</param> /// <returns></returns> public double GetMoney(ProductFather[] pros) { //声明一个总价钱 double realMoney = 0; for (int i = 0; i < pros.Length; i++) { //表示把这个集合当每一个货物的价钱累加到总价上 realMoney += pros[i].Price; } return realMoney; } }
}对象
打折方式的类建立
因为打折也是不固定没,没有能够直接实现的对象,因此这时就能够采用一个抽象类来实现
建立打折类的父类
namespace 超市收银系统 { /// <summary> /// 打折的父类 /// </summary> abstract class CalFather { /// <summary> /// 计算打折后应付多少钱 /// </summary> /// <param name="realMoney">打折前应付的钱</param> /// <returns>返回打折后的钱</returns> public abstract double GetTotalMoney(double realMoney); } }
有了打折类父类以后,按照需求了解到,有三种打折模式1.不打折 2.按照折扣打折 3.买多少送多少。先建立一个不打折的类
namespace 超市收银系统 { /// <summary> /// 不打折,该多少钱就是多少钱 /// </summary> class CalNormal : CalFather { public override double GetTotalMoney(double realMoney) { return realMoney; } } }
而后在建立一个按照折扣率打折的类
namespace 超市收银系统 { /// <summary> /// 按照折扣率打折 /// </summary> class CalRate : CalFather { /// <summary> /// 折扣率,因为天天的折扣率都不同,因此须要一个属性来存折扣率 /// </summary> public double Rate { get; set; } //当建立对象的时候传入折扣率 public CalRate(double reta) { this.Rate = reta; } public override double GetTotalMoney(double realMoney) { return realMoney * this.Rate; } } }
最后建立一个买多少送多少的类
namespace 超市收银系统 { /// <summary> /// 买M元 送N元 /// </summary> class CalMN : CalFather { //买多少送多少 public double M //买的钱 { get; set; } public double N //送的钱 { get; set; } public CalMN(double m, double n) //经过构造函数把值赋值给属性 { this.M = m; this.N = n; } /// <summary> /// 判断买多少钱(M)送多少钱(N) /// </summary> /// <param name="realMoney">买的多少钱</param> /// <returns>返回送钱后的应该付多少钱</returns> public override double GetTotalMoney(double realMoney) { if (realMoney >= this.M) { //此时存在一个问题,若是用户购买1000呢?送不送就得送两个100元。 //return realMoney - this.N; //打折多少取决于有几个M,这样就拿到了几个M,因为realMoney是double类型,因此须要强转成int整数型 return realMoney - (int)(realMoney/this.M)*this.N; } else { return realMoney; } } } }
至此超市打折的步骤完成
这时候咱们实际是不知道用户会选择哪一种打折模式的,这时候就用到了简单工厂设计模式,根据用户输入来返回一个对象。
因为不肯定用户的选择,因此也不能肯定返回哪一个子类,可是返回父类是确定不会错的。
获取用户选择的打折模式,来给出价钱
class SuperMarket { //当用户进入超市后,仓库应该有东西,可是作完仓库类后依然没有货,建立仓库对象经过构造函数给予仓库货 CangKu ck = new CangKu(); /// <summary> /// 建立超市对象的时候,给仓库的货架上导入货物 /// </summary> public SuperMarket() { ck.GetPros("ShouJi", 1000); ck.GetPros("NoteBook", 1000); ck.GetPros("JiangYou", 1000); ck.GetPros("banana", 1000); } /// <summary> /// 跟客户交互的过程(问客户买什么) /// </summary> public void AskBuying() { Console.WriteLine("欢迎光临,请问您须要些什么"); Console.WriteLine("咱们这里有笔记本电脑(NoteBook)、手机(ShouJi)、酱油(JiangYou)、香蕉(Banana)"); string strType = Console.ReadLine(); Console.WriteLine("您须要多少?"); int count = Convert.ToInt32(Console.ReadLine()); //去仓库取货 ProductFather[] pros = ck.QuPros(strType, count); //取货后,计算价钱,写一个方法,计算总价钱 double realMoney = GetMoney(pros); //打折方式 Console.WriteLine("您购买的商品,总价是{0}元", realMoney); Console.WriteLine("请选择你的打折方式 1--不打折 2--打九折 3--打85折 4--买300送50 5--买500送100"); string input = Console.ReadLine(); //经过简单工厂设计模式根据用户的输入得到一个打折对象 CalFather cal = GetCal(input); double totalMoney = cal.GetTotalMoney(realMoney); Console.WriteLine("打完折后,您应付{0}元", totalMoney); } /// <summary> /// 根据用户选择的打折方式返回一个打折对象 /// </summary> /// <param name="input">用户的选择</param> /// <returns>返回父类的对象,可是里面装的是子类对象</returns> public CalFather GetCal(string input) { CalFather cal = null; switch (input) { case "1": cal = new CalNormal(); break; case "2": cal = new CalRate(0.9); break; case "3": cal = new CalRate(0.85); break; case "4": cal = new CalMN(300, 50); break; case "5": cal = new CalMN(500, 100); break; } return cal; } /// <summary> /// 根据用户买的货物计算总价钱 /// </summary> /// <param name="pros">用户购买的货物</param> /// <returns></returns> public double GetMoney(ProductFather[] pros) { //声明一个总价钱 double realMoney = 0; for (int i = 0; i < pros.Length; i++) { //表示把这个集合当每一个货物的价钱累加到总价上 realMoney += pros[i].Price; } return realMoney; } }
当程序运行后,咱们想看见这个超市有什么东西,多少钱,即展现货物,而展现货物的方法已经写在仓库类中,按理说应该在Main函数中建立仓库的对象,这个时候有一个问题,建立对象的时候仓库里面只有货架,而没有货物。货物是在建立超市对象时候才有的
在超市类最下面调用仓库类中的展现货物的函数,这样就不用再到Main函数中建立仓库对象
/// <summary> /// 调用仓库展现货物的方法,这样就不用再去Main函数中建立仓库的对象 /// </summary> public void ShowPros() { ck.ShowPros(); }
写完这里,咱们的程序基本完成,在Main函数中建立超市对象并调用
class Program { static void Main(string[] args) { //建立超市对象 SuperMarket sm = new SuperMarket(); //1.展现货物 sm.ShowPros(); //2.跟用户进行交互 sm.AskBuying(); Console.ReadKey(); }
最后超市完成购物后,会打印一个小票
public void AskBuying() { Console.WriteLine("欢迎光临,请问您须要些什么"); Console.WriteLine("咱们这里有笔记本电脑(NoteBook)、手机(ShouJi)、酱油(JiangYou)、香蕉(Banana)"); string strType = Console.ReadLine(); Console.WriteLine("您须要多少?"); int count = Convert.ToInt32(Console.ReadLine()); //去仓库取货 ProductFather[] pros = ck.QuPros(strType, count); //取货后,计算价钱,写一个方法,计算总价钱 double realMoney = GetMoney(pros); //打折方式 Console.WriteLine("您购买的商品,总价是{0}元", realMoney); Console.WriteLine("请选择你的打折方式 1--不打折 2--打九折 3--打85折 4--买300送50 5--买500送100"); string input = Console.ReadLine(); //经过简单工厂设计模式根据用户的输入得到一个打折对象 CalFather cal = GetCal(input); double totalMoney = cal.GetTotalMoney(realMoney); Console.WriteLine("打完折后,您应付{0}元", totalMoney); Console.WriteLine("如下是您的购物信息"); foreach (var item in pros) { Console.WriteLine("货物:" + item.Name + "," + "\t" + "货物单价" + item.Price + "," + "\t" + "货物编号:" + item.ID); } Console.WriteLine("打完折后,您应付{0}元", totalMoney); }
至此超市收银系统练习完成!!