码迷,mamicode.com
首页 > 其他好文 > 详细

【大话设计模式】——简单工厂模式

时间:2017-07-26 21:57:52      阅读:183      评论:0      收藏:0      [点我收藏+]

标签:reading   调用   rtti   south   ediff   rgs   creat   orm   依次   

一、概念

  简单工厂模式(Simple Factory Pattern)属于创建型模式,又叫做静态工厂方法模式(Static FactoryMethod Pattern),可是不属于23GOF设计模式之中的一个。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。


二、UML图

  简单工厂主要分为三个角色:工厂(Creator)角色、抽象产品(Product)角色、详细产品(Concrete Product)角色。

  工厂角色:该模式核心,它负责创建全部实例的内部逻辑。工厂类能够被外界直接调用。创建所须要的产品。

  抽象产品角色:所创建的全部对象的父类,它负责描写叙述全部实例所共同拥有的公共接口。

       详细产品:该模式的创建目标,全部创建的对象都是充当这个角色的某个详细类的实例。

技术分享


三、实例解析

  下面是我自己想的一个简单工厂模式场景。假设有不妥的地方还请大家指出。

  我做的是一个简易的网吧收费系统。CashFactory充当的是工厂的角色,它会告诉我们怎样创建白天收费方式和晚上收费方式,须要实例化哪些对象,须要什么參数;详细产品 白天、晚上 收费方法。通过override,实现了从基类继承成员的新实现。网吧收费抽象类 为白天和晚上 收费方式的父类,描写叙述了两者的公共接口。


技术分享


代码例如以下:

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 WindowsFormsApplication2
{
    public partial class 简易网吧收费系统 : Form
    {
        public 简易网吧收费系统()
        {
            InitializeComponent();
        }

        //窗口启动的时候载入收费方式,是晚上收费,还是白天收费
       private void Form1_Load(object sender, EventArgs e)
        {
            cbxTimeType.Items.AddRange(new object[] { "白天", "晚上" });//在时间段的选择框里载入收费选项  白天。晚上
            cbxTimeType.SelectedIndex = 0;//索引从0開始,从下往上依次递增
        }

        //单击開始button之后,收费系统開始计时
       private void btnOK_Click(object sender, EventArgs e)
       {
           lbxList.Items.Add(cbxTimeType .Text );
           txtStartTime.Text = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");//開始时间文本框获取開始时间
           lbxList.Items.Add("開始时间:" + txtStartTime.Text);//同一时候在以下的列表框中载入開始时间信息
       }
        
        //单击停止button后,收费系统停止计时
        private void btnStop_Click(object sender, EventArgs e)
        {
            txtEndTime.Text = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
            lbxList.Items.Add("结束时间:" + txtEndTime.Text);

        }  

       //单击结账button,系统開始结账
        private void btnCharge_Click(object sender, EventArgs e)
        {
            double timeThrough = 0.0d;//定义一个变量timeThrough代表花费的时间(小时)
            DateTime DateTime1, DateTime2;//定义两个时间变量
            DateTime1 = Convert.ToDateTime(txtStartTime.Text);//把文本框中的时间从字符串格式转换成时间格式
            DateTime2 = Convert.ToDateTime(txtEndTime.Text);

            string DateDiff = null;//定义变量时间差(x天x小时x分钟x秒)

            TimeSpan ts1 = new TimeSpan(DateTime1.Ticks);
            TimeSpan ts2 = new TimeSpan(DateTime2.Ticks);
            TimeSpan ts = ts1.Subtract(ts2).Duration();
            
            //计算时间差
            DateDiff = ts.Days.ToString() + "天" + ts.Hours.ToString() + "小时" + ts.Minutes.ToString() + "分钟" + ts.Seconds.ToString() + "秒";
            timeThrough = Convert.ToDouble (ts.Days.ToString ()) * 24 + Convert.ToDouble (ts.Hours.ToString()) + Convert.ToDouble (ts.Minutes.ToString()) / 60 +Convert.ToDouble ( ts.Seconds.ToString() )/ 3600;          
            lbxList.Items.Add("通过时间:" + DateDiff);

            //利用简单工厂模式依据下拉选择框,生成对应的对象。
            BarCharge  barCharge = CashFactory.createCashAccept(cbxTimeType.SelectedItem.ToString());
            double money = 0d;
            money = barCharge.acceptCash(Convert.ToDouble(timeThrough) * 2);
            lbxList.Items.Add("需要支付上网的费用:" + money +"元");//通过多态,能够得到收取费用的结果
        }
   
    }


    //创建一个网吧现金收取的抽象类
     abstract class BarCharge
     {
         public abstract double acceptCash(double money);//收取现金,參数为原价。返回为当前价
     }


    //网吧的收费机制分为白天和晚上收费两种情况

     class Day : BarCharge //白天收费情况
     {
         public override double acceptCash( double money)
         {
             return money  ;//白天收费,返回钱数
         }
     }

     class Night : BarCharge //晚上收费情况
     {
         private double moneyRebate = 1d;
         
         //晚上收费。初始化必需要输入收费条件,晚上优惠率
         public Night(string moneyRebate)
         {
             this.moneyRebate = double.Parse(moneyRebate);   
         }
         //晚上收费=晚上收费*优惠率
         public override double acceptCash(double money)
         {
             
             return money * moneyRebate ;
         }
     }

    //现金收费工厂类
     class CashFactory
     {
         public static BarCharge createCashAccept(string type)
         {
             BarCharge bc = null;
             switch (type)//依据条件返回白天和晚上收费情况
             {
                 case "白天":
                     bc = new Day();//实例化对象
                     break;
                 case "晚上":
                     bc = new Night("0.8");//给出必要參数
                     break;
             }
             return bc;
         }
     }




}


执行结果:

技术分享

简单工厂攻克了对象的创建问题,免除了直接创建对象的步骤,实现了责任的切割。

可是因为工厂本身包含了全部的收费方式。每次维护或者扩展收费方式都要修改这个工厂,以至于代码须要又一次编译部署。这样违背了开放-封闭原则。


四、感受

  走别人的的路,不如自己 to do (不如的意思是更)。

先敲书上的样例,第一遍或许不懂,第二遍就清晰非常多。第三遍就认为自己能写点东西出来。不要总是认为自己看不懂,学不好,仅仅有先学了才干更好。没有之前的8个馒头,就没有第9个馒头的饱(好撑啊~~)。

【大话设计模式】——简单工厂模式

标签:reading   调用   rtti   south   ediff   rgs   creat   orm   依次   

原文地址:http://www.cnblogs.com/blfbuaa/p/7241623.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!