面向对象的六大原则-Android设计模式

面向对象有六大原则:单一职责原则、开闭原则、里氏替换原则、依赖倒置原则、接口隔离原则、迪米特原则。

单一职责原则

单一职责原则英文名:Single Responsibility Principle ,缩写是SRP.SRP的定义是:就一个类而言,应该仅有一个引起它变化的原因。一个类中应该是一组相关性很高的函数,数据的封装。

定义:

不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责。

问题由来:

类T负责两个不同的职责:职责P1,职责P2。当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责P2功能发生故障。

解决方案:

遵循单一职责原则。分别建立两个类T1、T2,使T1完成职责P1功能,T2完成职责P2功能。这样,当修改类T1时,不会使职责P2发生故障风险;同理,当修改T2时,也不会使职责P1发生故障风险

遵循单一职责原的优点有:

1,可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多;
2,提高类的可读性,提高系统的可维护性;
3,变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响。
4,需要说明的一点是单一职责原则不只是面向对象编程思想所特有的,只要是模块化的程序设计,都适用单一职责原则。
https://blog.csdn.net/IBelieve1974/article/details/54898341

开闭原则

开闭原则英文全称:Open Close Principle,缩写是OCP.
开闭原则,顾名思义,对扩展开放,对修改封闭.

开闭原则的定义:

软件中的对象(类、模块、函数等)应该对于扩展是开放的。但修改是封闭的。

开闭原则和依赖倒置原则

追求的结果是完全一样的,所有类都去依赖于抽象类。只是角度,不一样,依赖倒置原则是从这样的角度谈得,通常习惯性设计是高层依赖低层,现在变为低层依赖高层定义的接口。而开闭原则谈的是,加入抽象类,低层便于扩展,高层代码可以保持不变。

里氏替换原则

里氏替换原则英文全称是Liskov Substitution Principle.缩写是LSP.

定义:

所有引用基类的地方必须能透明的使用其子类的对象。
通俗讲:只要父类能出现的地方子类就可以出现。而且替换为子类也不会产生任何错误或异常,使用者可能不知道是子类还是父类。但反过来就不行,有子类出现的地方父类未必就能适应。

面向对象的三大特点:封装、继承、多态。
LSP就是依赖于继承、多态。
LSP的核心原理是抽象。
Liskov替换原则核心就是子类能完全替换它的基类。


LSP.jpg

依赖倒置原则

依赖倒置原则英文全称是Dependence Inversion Principle.缩写是DIP.
依赖倒置原则关键点:
1,高层模块不应该依赖底层模块,两者应该依赖其抽象。
2,抽象不应该依赖细节。
3,细节应依赖抽象。
在Java语言中,抽象就是指接口后抽象类,两者都是不能直接被实例化的。细节就是实现类,实现接口或继承抽象类而产生的类就是细节,其特点是可以直接被实例化,也就是加上一个关键字new产生一个对象。高层模块就是调用端,低层模块就是具体实现类。依赖倒置原则在Java语言中的表现就是:模块间的依赖通过抽象发送,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的。
其实就是面向接口编程或是面向抽象编程。这里的抽象指的是接口或抽象类。
看看依赖倒置是怎样解决这个问题的?它的两个原则:

  1. 高层模块不该依赖于低层模块, 二者都该依赖于抽象

  2. 抽象不应该依赖于细节,细节应该依赖于抽象


    DIP.jpg
public interface ICar
{
void Run();
void Turn();
void Stop();
}
public class BmwCar implements  ICar
{
public void Run()
{
Console.WriteLine("宝马开始启动了");
}
public void Turn()
{
Console.WriteLine("宝马开始转弯了");
}
public void Stop()
{
Console.WriteLine("宝马开始停车了");
}
}
public class FordCar implements  ICar
{
publicvoidRun()
{
Console.WriteLine("福特开始启动了");
}
public void Turn()
{
Console.WriteLine("福特开始转弯了");
}
public void Stop()
{
Console.WriteLine("福特开始停车了");
}
}
public class HondaCar implements ICar
{
publicvoidRun()
{
Console.WriteLine("本田开始启动了");
}
public void Turn()
{
Console.WriteLine("本田开始转弯了");
}
public void Stop()
{
Console.WriteLine("本田开始停车了");
}
}
public class AutoSystem
{
private ICar icar;
public AutoSystem(ICar icar)
{
this.icar=icar;
}
private void RunCar()
{
icar.Run();
}
private void TurnCar()
{
icar.Turn();
}
private void StopCar()
{
icar.Stop();
}
}
UML类图基础了解

https://www.cnblogs.com/pangjianxin/p/7877868.html

接口隔离原则

接口隔离原则英文全称是interface Segregation Principles。缩写是ISP,

接口隔离原则定义:

客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。
ISP将非常庞大,臃肿的接口拆分成更小的和更具体的接口,这样客户只需要知道他感兴趣的方法。
ISP的目的是系统解开耦合,从而容易重构,更改和重新部署。


ISP.jpg

见上图,该把接口细分到3个接口中去,保证每个类都只实现它需要的接口。

接口隔离原则与单一职责原则有什么区别呢?

单一职责原则,是指一个类只应该响应一个变化。比如一个赛马的程序,需要两个功能一是记每匹马跑的圈数,另一个是计算谁是对每匹马计算最终得分。 这两个功能有一点的联系,但是外部调用有可能只需要统计每匹马跑的圈数。所以要把这两个功能写到一个类里面。否则违反了单一职责原来。


ISP_UML.jpg
interface IOrderForPortal{
    String getOrder();
}
interface IOrderForOtherSys{
    String insertOrder();
    String getOrder();
}
interface IOrderForAdmin{ //extendsIOrderForPortal,IOrderForOtherSys
    String deleteOrder();
    String updateOrder();
    String insertOrder();
    String getOrder();
}
/*
interface IOrderForPortal{
    String getOrder();
}
interface IOrderForOtherSys{
    String insertOrder();
}
interface IOrderForAdmin extendsIOrderForPortal,IOrderForOtherSys{
    String updateOrder();
    String deleteOrder();
}
*/
class Order implements IOrderForPortal,IOrderForOtherSys,IOrderForAdmin{
    private Order(){
        //--什么都不干,就是为了不让直接 new,防止客户端直接New,然后访问它不需要的方法.
    }
    //返回给Portal
    public static IOrderForPortal getOrderForPortal(){
        return (IOrderForPortal)new Order();
    }
    //返回给OtherSys
    public static IOrderForOtherSys getOrderForOtherSys(){
        return (IOrderForOtherSys)new Order();
    }
    //返回给Admin
    public static IOrderForAdmin getOrderForAdmin(){
        return (IOrderForAdmin)new Order();
    }
    //--下面是接口方法的实现.只是返回了一个String用于演示
    public String getOrder(){
        return "implemented getOrder";
    }
    public String insertOrder(){
        return "implemented insertOrder";
    }
    public String updateOrder(){
        return "implemented updateOrder";
    }
    public String deleteOrder(){
        return "implemented deleteOrder";
    }
}
public class TestCreateLimit{
    public static void main(String[] args){
        IOrderForPortal orderForPortal =Order.getOrderForPortal();
        IOrderForOtherSys orderForOtherSys =Order.getOrderForOtherSys();
        IOrderForAdmin orderForAdmin = Order.getOrderForAdmin();
        System.out.println("Portal门户调用方法:"
+orderForPortal.getOrder());
        System.out.println("OtherSys外部系统调用方法:"
+orderForOtherSys.insertOrder());
        System.out.println("Admin管理后台调用方 
 法:"+orderForAdmin.getOrder()+";"
    +orderForAdmin.insertOrder()+";"
    +orderForAdmin.updateOrder()+";"
    +orderForAdmin.deleteOrder());
    }
}

SOLID:单一职责,开闭原则,里氏替换,接口隔离,依赖倒置。这几个关键字:抽象,单一职责,最小化。

迪米特原则

迪米特原则英文全称为Law of Demeter. 缩写是LOD,也称为最少知识原则(Least Knowledge Principle)。
一个对象应该对其他对象有最少的了解。
通俗讲:一个类应该对自己需要耦合或调用的类知道的最少,类的内部实现与调用者或者依赖者没关系,调用者或依赖者只需要知道它需要的方法即可。


LOD.jpg
//房间
public class Room {
    public float area;
    public float price;
    public Room(float area, float price) {
        this.area = area;
        this.price = price;
    }
    @Override
    public String toString() {
        return "Room [area="+area+",price="+price+"]";
    }
}
//中介
public class Mediator {
List<Room> mRooms=new ArrayList<>();

    public Mediator() {
        for (int i=0;i<5;i++){
            mRooms.add(new Room(14+i,(14+i)*1500));
        }
    }
    public Room rentOut(float area,float price){
        for (Room room:mRooms){
            if (isSuitable(area,price,room)) {
                return  room;
            }
        }
        return  null;
    }
    private boolean isSuitable(float area,float price,Room room)
{
        return room.price<=price&&room.area>=area;
    }
}
//租户
public class Tenant {
 public void rentRoom(float roomArea,
     float roomPrice,Mediator mediator){
      System.out.printf("租到房啦"+
         mediator.rentOut(roomArea,roomPrice));
 }
}

迪米特法则又叫最少知道原则。通俗的来讲,就是一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类来说,无论逻辑多么复杂,都尽量地的将逻辑封装在类的内部,对外除了提供的public方法,不对外泄漏任何信息。
迪米特法则还有一个更简单的定义:只与直接的朋友通信。首先来解释一下什么是直接的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。
耦合的方式很多,依赖、关联、组合、聚合等。其中,我们称出现成员变量、方法参数、方法返回值中的类为直接的朋友,而出现在局部变量中的类则不是直接的朋友。
也就是说,陌生的类最好不要作为局部变量的形式出现在类的内部。
举一个例子:有一个集团公司,下属单位有分公司和直属部门,现在要求打印出所有下属单位的员工ID。
从逻辑上讲总公司只与他的分公司耦合就行了,与分公司的员工并没有任何联系,这样设计显然是增加了不必要的耦合。
按照迪米特法则,应该避免类中出现这样非直接朋友关系的耦合

class SubCompanyManager{
    public List<SubEmployee> getAllEmployee(){
        List<SubEmployee> list = new ArrayList<SubEmployee>();
        for(int i=0; i<100; i++){
            SubEmployee emp = new SubEmployee();
            //为分公司人员按顺序分配一个ID
            emp.setId("分公司"+i);
            list.add(emp);
        }
        return list;
    }
    public void printEmployee(){
        List<SubEmployee> list = this.getAllEmployee();
        for(SubEmployee e:list){
            System.out.println(e.getId());
        }
    }
}
 
class CompanyManager{
    public List<Employee> getAllEmployee(){
        List<Employee> list = new ArrayList<Employee>();
        for(int i=0; i<30; i++){
            Employee emp = new Employee();
            //为总公司人员按顺序分配一个ID
            emp.setId("总公司"+i);
            list.add(emp);
        }
        return list;
    }
    
    public void printAllEmployee(SubCompanyManager sub){
        sub.printEmployee();
        List<Employee> list2 = this.getAllEmployee();
        for(Employee e:list2){
            System.out.println(e.getId());
        }
    }
}

public class Client{
    public static void main(String[] args){
        CompanyManager e = new CompanyManager();
        e.printAllEmployee(new SubCompanyManager());
    }
}

<Android源码设计模式解析与实战>读后感;记录下。方便回顾。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 197,099评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,846评论 2 374
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 144,146评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,789评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,656评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,467评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,870评论 3 389
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,500评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,790评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,828评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,628评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,449评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,881评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,077评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,376评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,879评论 2 343
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,089评论 2 338

推荐阅读更多精彩内容