zoukankan      html  css  js  c++  java
  • 设计模式之一 简单工厂模式

    今天分享设计模式中最简单的一种模式 简单工厂模式。先从面向对象说起,面向对象有三大特性:继承,封装,多态。

    所谓封装:在面向对象语言中,我们都是以类来组织代码,类中定义了属性和方法,我们在调用的时候只需要去使用对象的方法名或者属性名就可以了,而不必甚至不需要知道方法的具体实现,类比生活中的例子,榨汁机。我们只知道用它可以榨果汁,放个苹果给我们一杯苹果汁,放个桔子给我们一杯桔子汁就可以了。我们不必要去关心 榨汁机是怎么去工作的。

    所谓继承:就是子类继承了父类,父类所有的非私有的方法和属性,子类都可以拿来直接使用。就好比生活中,父亲给儿子留了一笔遗产。你可以直接使用这笔钱而不需要去创造这笔钱然后在去使用。

    所谓多态:一个类可以有多个子类,而每个子类只能由一个父类,就好比。一个父亲可以有多个儿子,而每个儿子只可以有一个父亲。对于多态我们有2种理解。第一种是不同的人对同一件事所做的不同反应,例如 工作,对于农民来说就是种地,科学家 搞科研,工人 上班,学生 做作业。第二种是同一个人 在不同情况下,具有不同的身份和角色,例如 同样是你,在公司你可能是员工,在家里 你是你父母的儿子,在路上你是行人。

    先来看一个简单的例子:

    我们首先定义一个父类Person类:

        /// <summary>
        /// 定义父类Person
        /// </summary>
        public class Person
        {
            public string Name { get; set; }
            public int Age { get; set; }

            /// <summary>
            /// 自我介绍
            /// </summary>
            public void SayHi()
            {
                Console.WriteLine("大家好我是" + Name + ",我今年" + Age + "岁了!");
            }
        }

     定义2个子类,一个Student类,一个Teacher类

     public class Student : Person
        {
        }

     public class Teacher: Person
        {
        }

    在控制台中访问:

     static void Main(string[] args)
            {
                Student s = new Student();
                s.Name = "张三";
                s.Age = 20;
                s.SayHi();
            }

    输出:

    可以看出子类是可以使用父类的非私有的属性和方法。

    当然 老师的自我介绍和学生自我介绍肯定不一样。如果我们要实现 老师的自我介绍是 大家好。我是XX老师,我今年工作几年了。 学生的自我介绍是大家好。我是某某学生,我今年多少岁了,应该怎么做呢。

    如下图:

    编译器会有警告,因为我们在基类中已经使用了SayHi方法来做自我介绍。为了能更好的解决问题。我们就要用到多态了。

    我们把基类Person类改写成抽象类,把基类中的SayHi方法改写成抽象方法。

    直接上图:

     /// 定义父类Person
        /// </summary>
        public abstract class Person
        {
            public string Name { get; set; }
            public int Age { get; set; }

            /// <summary>
            /// 自我介绍
            /// </summary>
            //public void SayHi()
            //{
               // Console.WriteLine("大家好我是" + Name + ",我今年" + Age + "岁了!");
            //}
            /// <summary>
            /// 抽象方法,自我介绍
            /// 抽象方法没有具体实现,只能通过子类覆写来实现。
            /// </summary>
            public abstract void SayHi();
        }

    子类

     public class Teacher : Person
        {
            public int YearOfWork { get; set; }

            public override void SayHi()
            {
                Console.WriteLine("大家好我是" + Name + "老师,我工作" + YearOfWork + "年了!");
            }
        }

     public class Student : Person
        {
            /// <summary>
            /// 重写基类自我介绍方法
            /// </summary>
            public override void SayHi()
            {
                Console.WriteLine("大家好我是" + Name + ",我今年" + Age + "岁了!");
            }
        }

    在Main方法中 定义如下

    static void Main(string[] args)
            {
                Teacher t = new Teacher();
                t.Name = "AAA";
                t.YearOfWork = 5;
                t.SayHi();

                Person p = new Teacher() { Age = 18, Name = "李四", YearOfWork = 5 };
                p.SayHi();
            }

    输出结果

    如上图 我们可以看到 p 和t 都是调用的teacher类中的sayhi方法。 这就是多态。子类通过覆写 父类中的抽象方法或者虚方法来实现。

    这个也叫里氏替换原则 就是凡是父类出现的地方子类都可以出现。 试想一下 如果 Person类不定义为抽象类。以上2个输出结果会有什么不同。

    简单工厂正是 基于以上原则来实现的。

    以上是对面向对象的一个简单回顾。下面我们来讲 简单工厂设计模式。设计模式不是一种新的技术,只是在编写代码中一些好的方式的积累和经验的积累。

     从上图 我们可以看出:

    从结构可以看出,工厂依赖于所有的子类产品,客户只需知道父类产品和工厂即可。工厂是整个模式的核心,以不变应万变。

    在现实生活中 我们知道。工厂是用来生产产品的。在面向对象的技术里面工厂也是用来生产产品的。在这里我们的工厂是用来给类生产对象的。

    在前面我们简单介绍过封装 继承 多态。那么在使用简单工厂模式的时候我们首先要定义好角色。父类 ,子类 和工厂类。 子类继承父类。 父类定义子类要实现的方法。工厂 创建类的对象。客户调用的时候只需要 知道工厂类和父类就可以了。上图红线标注。

    我们以生活中的例子来说明。

    首先我们创建一个父类 。我们知道车有很多。什么宝马 奔驰。等等。我们先定义一个父类 。小汽车类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace Demo
    {
        /// <summary>
        /// 父类
        /// </summary>
        public abstract class Car
        {
            public abstract void Run();
        }
    }

    在来定义2个子类 ,子类继承父类

    一个是宝马汽车类:

    /// <summary>
        /// 子类1
        /// </summary>
       public class BMWCar:Car
        {
            public override void Run()
            {
                Console.WriteLine("宝马轿车在行驶!");
            }
        }


        /// <summary>
        /// 子类2
        /// </summary>
        public class BenzCar:Car
        {
            public override void Run()
            {
                Console.WriteLine("奔驰轿车在行驶!");
            }
        }

    在来定义一个工厂类

     /// <summary>
        /// 工厂
        /// </summary>
       public class Factory
        {
           public static Car CreateCar(string carType)
           {
               Car car = null;
               switch (carType)
               {
                   case "BMW":
                       car = new BMWCar();
                       break;
                   case "Benz":
                       car = new BenzCar();
                       break;
               }
               return car;
           }
        }

    在工厂类中。我们定义了一来Create方法。用来创建对象。通过父类对象来返回我们创建的对象。

    在Main方法 中调用 就是上图中的客户端。我们只需要关注父类和工厂 。

     Car car = Factory.CreateCar("Benz");
     car.Run();

    运行结果 就是 :奔驰汽车在行驶。

  • 相关阅读:
    win2008R2、win7不停闪屏、程序失去响应的解决办法
    “我要上春晚”刷票器
    Windows Phone 7的About模板——Your Last About Dialog
    该伙伴事务管理器已经禁止了它对远程/网络事务的支持
    安装配置apache+php+mysql小结
    [摘]CSS的优先级探讨
    利用domdrag实现flash滚动条功能
    WIN7下如何做好IE6,7的兼容性测试
    同级情况下CSS的优先级探讨
    [NHibernate] NHibernate对象关系映射工具了解
  • 原文地址:https://www.cnblogs.com/TNSSTAR/p/2971043.html
Copyright © 2011-2022 走看看