前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >面向对象设计必须遵循的几条原则

面向对象设计必须遵循的几条原则

作者头像
木可大大
发布2018-07-25 15:11:07
3920
发布2018-07-25 15:11:07
举报
文章被收录于专栏:木可大大木可大大

我们知道软件开发的需求总是不完整的,错误的,容易让人产生误解的,而且需求一直在变化,它主要表现在以下几个方面:用户对需求的看法,可能在于开发人员讨论以及看到软件新的可能性后发生变化;随着对问题的熟悉,开发人员对问题领域的看法也会变化;不是需求在变,而是人们对需求的理解再变化。

我们应该采用何种方法去应对需求变化呢?首先,在方法论层面我们应该采用敏捷开发;其次,在代码层面,使用OOD(Object-Oriented Design,面向对象设计),它的根本原则:面向接口编程;多用组合,而不是继承;发现变化,封装变化。但如何让设计满足这个原则呢?我们的先辈们总结出了5条设计原则,俗称SOLID原则,这就是本期我们要介绍的详细内容。

单一职责原则(SRP,The Single Responsibility Principle)

Robert C. Martin 大师对于单一职责原则有这样一个定义:一个类应该仅有一个引起它变化的原因,而这个引起变化的原因就是职责。那么职责是什么东西呢?先来说说我们人类的职责。作为项目经理,我的职责是:项目计划、需求管理、项目成本控制、项目时间控制等,我需要处理很多事情,同时,这些事紧密相关的。对应到面向对象设计领域,一个类的职责应该包含多个相关的功能。比如说用户控制类中一般包含了新增用户、删除用户、修改用户等相关功能。

开闭原则(OCP,The Open close Principle)

开闭原则就是说对扩展开发,对修改封闭。看到这里,我们不禁会问:新增功能还可以不用修改代码呀? 这是如何做到的呀?实际上开闭原则指的是提供者增加新的功能,而使用者不需要修改代码,并且增加的新功能不能是一个全新的功能,而是原有功能的替代实现。为了帮助大家理解,我举一个具体的例子。目前购物车有添加商品、计算价格两个功能,而商品有香蕉、苹果两种。Java代码如下:

代码语言:javascript
复制
public interface Item{  
    public String getName();  
    public float getPrice();
}
public class Apple implements Item {    
   public String getName() {        
        return "Apple";
   }    
   public float getPrice() {        
       return 5.0f;
   }
}
class Orange implements Item{    
   public String getName() {        
        return "Orange";
   }    
   public float getunitPrice() {        
       return 6.0f;
   }
}
public class ShopCar {
   List<Item> items = new ArrayList<Item>();    
   public void addItem(Item item) {
       items.add(item);
   }    
   public float calculateTotalPrice() {        
       float total = 0.0f;        
       for (Item i : items) {
          total += i.getPrice();
       }        
       return total;
   }
}

我们注意到当新增一个香蕉类,ShopCar类不用修改,这是因为香蕉类是原有功能的替代实现,而不是一个全新的功能,如果购物车中新增商品价格变化这一全新功能,则需要修改ShopCar类。

Liskov替换原则(LSP,The Liskov Substitutuin Principle)

LSP替换原则指的是:子类型能够完全替换父类。它最经典的例子就是长方形和正方形。我们知道正方形是一种特殊的长方形,但是在面向对象设计领域,正方形并不能作为长方形的子类。原因在于设置正方形的长或宽时,同时设置了它的宽或长,那么,正方形的面积等于最后一次设定的长或宽的平方,而不是长乘以宽。具体Java代码如下:

代码语言:javascript
复制
// 长方形
public class Rectangle {  
    protected int width;  
    protected int height;  
    public void setWidth(int width){    
        this.width = width;
     }  
    public void setHeight(int height){    
        this.height = height;
    }  
    public int area(){    
        return width*height;
    }
}
// 正方形
public class Squrare extends Rectangle{  
    public void setWidth(int width){    
        this.width = width;    
        this.height = height;
 }  
    public void setHeight(int height){     
        this.width = width;     
        this.height = height;
 }
}
// 测试类
public class Test{  
    public static void main(String[] args){  
       Rectangle rectangle = new Rectangle();  
       rectangle.setWidth(4);  
       rectangle.setHeight(5);  
       // 正确       
       assert( rectangle.getArea() == 20);  
         
       rectangle = new Square();  
       rectangle.setWidth(4);  
       rectangle.setHeight(5);  
       // 错误,此时正方形面积是25       
       assert( rectangle.getArea() == 20);  
   }  
}

判断一个子类是否满足LSP替换原则,我们可以像上面这个例子那样,在测试类中用子类来替换父类。如果测试能够通过,则说明符合LSP原则,否则就说明不符合LSP原则。

接口隔离原则(ISP,The Interface Segregation Interface)

虽然我们要求软件开发人员都要遵循SRP,但是很多情况下类是没有满足SRP原则的,这个时候就需要用到接口隔离原则。ISP原则指的是客户端不应该被强迫去依赖它们并不需要的接口。也就是说,调用方调用的不需要是一个大而全的接口,而是一个小而精的接口。

依赖倒置原则(DIP,The Dependency Inversion Principle)

DIP包含两层意思:1. 高层模块不应该直接依赖低层模块,两者都应该依赖抽象层;2. 抽象不能依赖细节,细节必须依赖抽象。这里模块是个广义概念,可以是系统、子系统、子模块,甚至是类。而依赖包含多层意思:高层模块调用底层模块的方法,底层模块继承或实现抽象层。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-05-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 木可大大 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 单一职责原则(SRP,The Single Responsibility Principle)
  • 开闭原则(OCP,The Open close Principle)
  • Liskov替换原则(LSP,The Liskov Substitutuin Principle)
  • 接口隔离原则(ISP,The Interface Segregation Interface)
  • 依赖倒置原则(DIP,The Dependency Inversion Principle)
相关产品与服务
项目管理
CODING 项目管理(CODING Project Management,CODING-PM)工具包含迭代管理、需求管理、任务管理、缺陷管理、文件/wiki 等功能,适用于研发团队进行项目管理或敏捷开发实践。结合敏捷研发理念,帮助您对产品进行迭代规划,让每个迭代中的需求、任务、缺陷无障碍沟通流转, 让项目开发过程风险可控,达到可持续性快速迭代。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档