深刻分析面向对象中的对象概念

  OOP:面向对象编程,一提到面向对象,你们可能就想到类,接口。一说特性,你们可能张口就来:继承、封装、多态,那么到底什么样的对象(类)才是真正意义上的对象呢?特别是如今流行的DDD领域驱动设计思想,讲究职责划分,那么如何定义一个对象(类)它应该具备的一些特性、行为方法及承担责任成为关键。程序员

  一个看似简单的问题,其实也是耐人思索,以前也在网上看到一些人关于讨论类的设计问题,认为设计类时不该该考虑数据库,我以为这只是实现真正的面向对象设计的基础,也是前提条件,大多数程序员以前都是受面向过程编程思想的影响,我(梦在旅途)也不例外,一个须要求下来,首先就是想它须要存哪些数据,建哪些表,要定义哪些个方法来完成数据的存储,整个过程基本是围绕数据库来进行的,我这里称之为数据驱动编程,这样开发其实也没有错,由于存在即有存在的道理,我也能够分析出这种编程的优势:开发速度快,执行效率高(没有层级或层级以前只是简单的转发),缺点是:可读性差,不利于后续的二次开发等,简单的应用程序或某个独立的核心模块使用这种编程方式我以为也是能够的,但除此以外,我仍以为合理的面向对象是有必要的,我这里强调合理,是不要一味的盲目采用某个框架或某种设计模式,没有最好的框架,一样也没有最好的设计模式,惟有最适合的框架与设计模式,那么如何评估框架与设计是否合适,我认为对象(类)的设计相当重要,下面就个人经验及我所看到的现象来谈谈的对象的设计问题,因为我不是什么大牛,因此不免表达有误的地方,请多包涵,固然也欢迎你们一块儿讨论。数据库

1.对象是什么?编程

在现实生活中,对象指的是某一个客观存在的事物,它具备能识别它惟一性的属性,好比:某人的某个品牌的某个型号的汽车,我这里为何用了多个某个,由于人+品牌+型号+汽车,就能肯定具对这个对象,而不是汽车这么简单,注意汽车并非一个对象,它只是表示的是某类事物,因此经过现实生活的分析,咱们能够转换思想到编程的世界中,来分析对象与类的区别。在编程中,类就是上面的汽车,而对象则是类的实例化,识别对象的惟一性从计算机的角色讲,应该是内存堆中地址,每个地址肯定一个对象。设计模式

2.对象有什么?框架

对象指的是具体的某个事物,除了有识别它惟一性的属性外,它应该还有如下几个特性:函数

1、状态(也能够简单的称之为属性):描述一个对象的特征,这个特征能够永久的,也能够是受外界影响而改变的,好比:某人的某个品牌的某个型号的汽车,若是这辆车从新喷漆,换了一种颜色,那么的它此时的状态,颜色被改变;若是车被卖给另一我的,那么它此时的状态,车的全部者也被改变了。post

代码示例:学习

    public class Car //这是一个类
    {
        public Car(string owner,string brand,string model,string color)
        {
            this.Owner = owner;
            this.Brand = brand;
            this.Model = model;
            this.Color = color;
        }

        public string Owner { get; set; }

        public string Brand { get; set; }

        public string Model { get; set; }

        public string Color { get; set; }
    }


        public static void Main(string[] args)
        {
            var car = new Car("张三", "宝马", "B01", "黑色");//这是一个对象
            car.Color = "红色";//状态被改变
            car.Owner = "李四";//状态被改变
        }

2、行为(也能够简单的称之为方法、函数):一个对象主动或被动去执行某种动做,好比:张三这我的,他吃饭,他看书,他睡觉等都是一种行为,包括我如今写博客也是一种行为。行为又分主动与被动,主动是指一个对象主观意识的动做,好比:张三吃饭就是主动,而被动则是需另外一个对象来命令它来执行某种动做,好比:汽车启动,启动是一个行为,但它不能本身启动,须要驾驶人去经过汽车给定的启动方法与步骤来请求汽车执行启动,又或者说是取款机,取款机提供一个取款的行为,而具体何时来取,取多少,均由人来告诉它。this

代码示例:设计

    public class Car //这是一个类
    {
        public Car(string owner,string brand,string model,string color)
        {
            this.Owner = owner;
            this.Brand = brand;
            this.Model = model;
            this.Color = color;
        }

        public string Owner { get; set; }

        public string Brand { get; set; }

        public string Model { get; set; }

        public string Color { get; set; }

        public string Status { get; private set; }


        public Driver Driver { get; set; }

        public void Start() //启动方法,被动
        {
            if (this.Driver!=null)
            {
                this.Status = "运行中";
            }
            else
            {
                throw new InvalidOperationException("没有驾驶员,不能自动启动!");
            }
        }

        public void Stop() //启动方法,被动
        {
            this.Status = "中止";
        }
    }


    public class Driver
    {
        public string Name { get; set; }

        public Driver(string name)
        {
            this.Name = name;
        }

        public void  Drive(Car car)//驾驶,主动
        {
            car.Driver = this; //坐在车上
            car.Start();//启动汽车,并运行
            car.Stop();//到达终点,中止汽车
        }
    }

    public class APP9
    {
        public static void Main(string[] args)
        {
            var car = new Car("张三", "宝马", "B01", "黑色");//这是一个对象
            var driver = new Driver("李四");
            driver.Drive(car);//李四来开张三的车,现实生活中不能随便借车开哦!~V~
        }
    }

有人看了上面的代码后,可能再想,不是全部的对象都有行为吧,既然是行为,行为又表明一种动做,那么也只有能动的对象才有行为,不能动的对象就没有,是这样吗?我在写这篇博文前也思考了这个问题,开始也这样认为的,后面仔细一想,不对,应该是全部的对象都有行为,就拿不动的东西来讲吧,好比一张纸,纸自己本是不能动的,但若是你把它扔起来,那么纸就具有了被动的移动方法,根据爱因斯坦的相对论,没有绝对的静止,只有相对的静止,因此就看在什么状况下,参照物是什么,有点扯远了哈,回归正题,有人可能仍是不服,全部的对象都有行为方法,那我不是非要对全部的类都定义方法吗,否则就不符合真正的对象?我认为不是这样的,场景决定一个对象的状态与方法,这也是下面我将要说明的角色定位的问题,这里我能够很负责任的告诉你,咱们全部的定义的对象都有行为,只是你没有意识到而矣,是什么呢?那就是构造函数与析构函数,它们就是被动的行为方法,这也是符合现实生活的对象,任何一个对象都有建立与毁灭,你敢说不是吗?请举出例子来吧!

3.对象角色定位

任何一个对象在不一样的场景中应该有不一样的状态及行为,好比:张三,张三在学校他是学生,具备学生的状态及行为,在公司工做他是员工,具备员工的状态及行为,取得驾照驾驶汽车,具有驾驶员的状态及行为,在图书馆看书,具有读者的状态与行为。由此可知,对象是复杂的,类是具体一些,对象存在多变性,而类则应具有不变性,可能有人不明白,我这里具体解释一下,我这里说的可变性,不是面向对象的那个多态,而是指对象角色的可变性,好比:学生类,那么它就表示学生,它不可能还表示做者,固然它能够表示人,但通常人不会这样表示,而对象则不一样,正如上面我讲的张三的不一样角色,他不一样类的实例化,类不支持多重继承,我以为对的,由于一个类能够表明一个角色,一个角色只能作这个角色的事情,好比:学生,他就是学习,老师,他就是教书,有人可能还会说,兼职多个角色,又是员工又是驾驶员,又是老师同时又是学生,是的,确实存在,但上面说过了,兼职的时候一个对象不可能同时作某个事情,好比:又是员工又是驾驶员,难道他同时工做又同时开车,有人说:出租车司机呀!好吧,你历害,但仍然是角色不一样,出租车司机开车就是工做,当他不工做开车时,他就是驾驶员。好了,说了这么多,看是来看一下代码示例吧!

    public class Person //人
    {
        public string IdNo{get;set;}

        public string Name { get; set; }

        public string Sex { get; set; }

        public double Height { get; set; }

        public double Weight { get; set; }

        public DateTime BirthDay { get; set; }

    }

    public class Post //文章
    {

        public string Title { get; set; }

        public string Content { get; set; }

        public Author Author { get; set; }
        
        public DateTime CreateDatetime { get; set; }

    }

    public class Author : Person //角色为做者
    {
        public void Write(Post post)
        {
            //行为
        }
    }


    public class Book //书
    {
        public string Name { get; set; }

        public DateTime IssuedDate { get; set; }

        public List<Post> Posts;

    }

    public class Library //图书馆
    {
        public string Name { get; set; }

        public List<Book> Books { get; set; }

        public void Borrow(Reader reader, IEnumerable<Book> books) //借出书,被动
        {
            Books.RemoveAll(b=>books.Contains(b));
            //其它操做
        }

        public void Return(Reader reader,IEnumerable<Book> books)//还入书,被动
        {
            Books.AddRange(books);
            //其它操做
        }
    }

    public class Reader : Person //角色为读者
    {
        public List<Book> Books { get; set; }

        public IEnumerable<Post> Read(Book book,params int[] pages) //读书,主动
        {
            var posts = new List<Post>();
            if (pages != null)
            {
                foreach(int i in pages)
                {
                    posts.Add(book.Posts[i]);
                }
            }
            else
            {
                posts = book.Posts;
            }
            return posts;
        }

        public void Borrow(IEnumerable<Book> books, Library library) //主动借书
        {
            library.Borrow(this,books);
            Books.AddRange(books);
        }

        public void Return(IEnumerable<Book> books, Library library)//主动还书
        {
            library.Return(this, books);
            Books.RemoveAll(b => books.Contains(b));
        }

    }

    public class Driver:Person //角色为驾驶员
    {
        public void Drive(Car car)
        {
            car.Driver = this;
            car.Start();
            car.Stop();
        }
    }

    public class Car
    {
        public Driver Driver { get; set; }

        public string Status{get;private set;}

        public void Start()
        {
            this.Status="运行中";
        }

        public void Stop()
        {
            this.Status="中止";
        }
    }

结 尾

我这里只是定义,没有列出运行时代码。例子比较简单,你们看一下就行了。最后要说明的是,对象虽然都有状态与行为,并且角色不一样状态与行为也随之不一样,但在编程的世界里,咱们能够只关注咱们所关注的,好比:一个博客系统,咱们只关注做者,阅读者,回复者三个角色,从这三个角色应该具有的状态与行为进行设计相关的类,这样就比较符合真实的对象了,也就不会出现你们常见的:状态类-僵尸类(只有属性,无方法),方法类-孤魂野鬼类(只有方法,无属性)

好了,文章到这里就结束了,面向对象的思想博大精深,很难一会儿所有说明白,但相信只要咱们在编程中多思考多总结就能提高咱们编程觉悟,有朝一日成为大师。在此向大师、大牛们致敬,向大家学习,学习的道路永远止境。这篇文章我花了一上午的时间,想了不少,写得却不是不少,但都是源自个人想法,若是帮助到你们了,还请支持推荐一下哦,很是感谢!

相关文章
相关标签/搜索