关于面向对象程序设计的一些思考

入职程序员做c++的,面向对象设计能力有些欠缺,最近想了一些记下来。这些想法未必是对的,但是也算是自己的一点思考,希望有经验的同事积极批评指正。

面向对象的设计分为两方面,基础类的设计和业务类的设计。

基础类分为和业务无关的基础类和和业务相关的基础类。举个例子,商场货物的管理系统,像文件读写、数据库增删改查、网络访问、日志系统等都是和业务无关的类,像商场下有哪些商店、商店下包含哪些仓库、哪些货架等、货架内有什么商品等都是和业务有关的类。

和业务无关的类一般可以在在各个项目中通用,类和类之间的关系并没有特别复杂,类的接口设计的越简单越好。和业务相关的类就相对复杂,只能用在当前的项目中。

类分为属性和方法。属性是对外提供的这个类描述的“性质”,方法是对外提供的功能。例如文件类

class File{
public:
    string filename;
    int read(char**,int&);
    int write(char*,int);
}

例如文件名就是类的属性,读和写是方法。当然,有些和文件相关的属性并不是那么容易获取的,例如文件的创建日期,文件的扩展名等,这些本是属性,但需要方法获取,可以成为方法属性。在C#里面,这一类的属性可以使用get\set更好的表示,并且它告诉别人,这也是属性。

public class File{
    //属性:文件名(可读、可写)
    public String FileName{
        get{ return m_filename; }
        set{ m_filename = value }
    }
    //属性:创建日期(只读)
    public String CreateTime{
        get{ ... }
    }
    private String m_filename;
}

在c++和Java里面,并没有c#属性的概念,只能使用get和set函数进行封装。但是在设计这个类的时候,要有和c#一样的思维,这个get是要获取这个属性,get和set本身并不应当看成类的方法。

在设计一个类的时候,要注意类对外需要提供什么属性和什么方法,对内不管是怎么设计的,对外都是不会被关注到。

类之间是有包含关系的,这个关系并不一定对编程有什么帮助,但是它却可以客观的反映现实世界。还是上面商场的例子:

Shops(商场){
    Shop(子分店){
        StoreHouse(仓库){
            Goods(商品){}
        }
        Shelves(货架){
            Goods(商品){}
        }
    }
}

商场和子公司是属于包含和被包含的关系,子公司和仓库、货架是属于包含和被包含的关系。像这种关系是自然概念确定的包含关系,和具体的业务也是没有关系的。但是不管是什么业务,类的设计上也需要去体现出这种包含和被包含的关系。

下面改说说具体的业务类。假如需求上描述,供应商获取一定的的某种商品,我需要去自动管理将这种商品分配到哪个子分店里,是放置到具体的货架上还是在保存到仓库里,这需要一定的分配策略,像根据各个子分店的购买力、商品剩余等等。这相相当于一个需求。这个过程是最好封装成一个类,因为这个过程涉及一些公共变量可以为类存储。

在设计类的时候,需要考虑到类需要对外提供哪些属性,外部的输入可以作为设计属性的重要依据,各个过程可以作为方法的依据。

class GoodsAllocation{
public:
    bool setGoods(const Good& good);
    bool setShops(const Shops& shops);
    void getInfo();
    void calc();
    void push();
}

商品分配类需要知道被分配的商品,需要知道商店的信息,步骤可能分成三步,先需要获取商店的信息到本地(可能涉及到数据库、网络等操作),计算分配,将分配好的结果保存到数据库或服务中。

这样的话,这个业务就被封装在一个类中了。当需求发生变化的时候,例如我需要修改分配的逻辑,就可以直接修改GoodsAllocation::calc方法。

我曾听过一个人说过这样一句话,当一个组件(类)提交给测试通过后,这个类便不再和程序员有任何的关联了,如果有变化,则需要重写开启一个研发任务。在需求如此变化的今天,一次性完成所有功能几乎是不太可能,但是往往改动的是业务,而非基础类,即基础类一旦提交测试,几乎就不太有改动的可能了,但业务类很有可能还是会变化的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值