zoukankan      html  css  js  c++  java
  • 大话设计模式-简单工厂模式

    简单工厂模式

    从父类派生出多个子类时,使用一个单独的类来做创造实例的过程,这就是工厂。

    下面举出两个实例进行介绍简单工厂模式的应用。


    简单计算器

    每种计算都是获取数,返回结果的过程,故而可以将每种计算单独封装为一个类,并继承父类Operation。在父类中声明一个虚方法GetResult,每种计算子类都要重写父类该方法以进行自己的计算。

    父类计算类:Operation

    public class Operation{
        //两数的属性、获得结果虚方法
        public double NumbleA { get; set; }
        public double NumbleB { get; set; }
        public virtual double GetResult() => default(double);       
    }

    派生的子类:OperationAdd、Sub、Mul、Div

    class OperationAdd : Operation{
        public override double GetResult() => NumbleA + NumbleB;
    }
    class OperationSub : Operation{
        public override double GetResult() => NumbleA - NumbleB;
    }
    class OperationMul : Operation{
        public override double GetResult() => NumbleA * NumbleB;
    }
    class OperationDiv : Operation{
        public override double GetResult(){
            if (NumbleB == 0) throw new Exception("除数不能为0");
            return NumbleA / NumbleB;
        }
    }

    工厂类:OperationFactory

    class OperationFactory{
        //根据输入的运算符进行判断生成哪种子类的静态方法
        public static Operation CreateOperate(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;
            }
            return oper;
        }
    }

    测试类:Program

    class Program{
        static void Main(string[] args){
            Console.WriteLine("请输入一个数:");
            double n1=Convert.ToDouble(Console.ReadLine());
            Console.WriteLine("请输入运算符:");
            var of=OperationFactory.CreateOperate(Console.ReadLine());
            Console.WriteLine("请输入一个数");
            double n2 = Convert.ToDouble(Console.ReadLine());
            of.NumbleA = n1;
            of.NumbleB = n2;
            Console.WriteLine($"运算结果为:{of.GetResult()}");
            Console.ReadKey();
        }
    }

    测试结果:控制台

    请输入一个数:
    5
    请输入运算符:
    /
    请输入一个数
    2
    运算结果为:2.5

    商场促销

    商场促销的分类不应该细分折扣或者满减级别,这样类就特别多,分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类。

    商场促销有原价、打折、满减等手段,收银台需要根据不同的活动,将总价带入不同优惠的计算公式中得出最终的价格,所以打折算法才应该是一个类。

    父类:现金收费抽象类

    提供了一个接受现金抽象方法

    abstract class CashSuper{
        public abstract double AcceptCash(double money);
    }

    子类:正常、打折、满减类

    根据不同的优惠,将优惠方法分为若干个类,这些类都要继承现金收费抽象类并重写接受现金抽象方法。

    class CashNormal : CashSuper{
        //返回原价
        public override double AcceptCash(double money) => money;
    }
    class CashRebate : CashSuper{
        //声明、初始化折扣
        private double moneyRebate = 1d;
        public CashRebate(double moneyRebate)=>this.moneyRebate = moneyRebate;
        //重写方法,计算折扣额
        public override double AcceptCash(double money) => money * moneyRebate;
    }
    class CashReturn : CashSuper{
        //声明、初始化满额和减额
        private double moneyCondition = default(double);
        private double moneyReturn = default(double);
        public CashReturn(double moneyCondition, double moneyReturn){
            this.moneyCondition = moneyCondition;
            this.moneyReturn = moneyReturn;
        }
        //重写方法,计算返回满减额
        public override double AcceptCash(double money){
            //将金额除以满额得到的数取整,乘以减额,得到满减额
            if (money >= moneyCondition)
                return money - Math.Floor(money / moneyCondition) * moneyReturn;
            return money;
        }
    }

    工厂类:现金工厂类

    根据选择的不同优惠,创建对应的现金收费类的子类

    class CashFactory{
        public static CashSuper CreateCashAccept(string type){
            CashSuper cs = null;
            switch (type){
                case "1":
                    cs = new CashNormal();//原价
                    break;
                case "2":
                    cs = new CashRebate(0.8);//八折
                    break;
                case "3":
                    cs = new CashReturn(300,100);//满300返100
                    break;
            }
            return cs;
        }
    }

    测试类:程序类

    测试数据

    class Program{
        static void Main(string[] args){
            Console.Write("请输入商品单价:");
            double foodSprice=double.Parse(Console.ReadLine());
            Console.Write("请输入商品数量:");
            double fooeNum = double.Parse(Console.ReadLine());
            Console.WriteLine($"1:原价{Environment.NewLine}2:八折{Environment.NewLine}3:满300返100");
            Console.Write("请选择优惠方式:");
            CashSuper cp=CashFactory.CreateCashAccept(Console.ReadLine());
            Console.WriteLine(cp.AcceptCash(foodSprice*fooeNum));
            Console.ReadKey();
        }
    }

    测试结果:控制台

    请输入商品单价:200
    请输入商品数量:5
    1:原价
    2:八折
    3:满300返100
    请选择优惠方式:3
    700

    注意

    工厂类虽然能解决这个问题,但是这份模式只是解决对象的创建问题,工厂包括了所有的收费方式,每次维护或者扩展都要改动这个工厂,可以使用策略模式改进程序。

  • 相关阅读:
    Atitit (Sketch Filter)素描滤镜的实现  图像处理  attilax总结v2
    JS设置cookie、读取cookie、删除cookie
    Atitit 图像处理30大经典算法attilax总结
    Atitit数据库层次架构表与知识点 attilax 总结
    Atitit 游戏的通常流程 attilax 总结 基于cocos2d api
    Atitti css transition Animation differ区别
    Atitit 图像清晰度 模糊度 检测 识别 评价算法 源码实现attilax总结
    Atitit 全屏模式的cs桌面客户端软件gui h5解决方案 Kiosk模式
    Atitit 混合叠加俩张图片的处理 图像处理解决方案 javafx blend
    Atitit  rgb yuv  hsv HSL 模式和 HSV(HSB) 图像色彩空间的区别
  • 原文地址:https://www.cnblogs.com/errornull/p/10012252.html
Copyright © 2011-2022 走看看