美文网首页
设计原则

设计原则

作者: EdwardWinner | 来源:发表于2018-09-21 13:56 被阅读1次

    单一职责原则

    单一职责原则的英文名称是Single Resposibility Principle,缩写 SRP

    SRP的定义是:
    就一个类而言,应该仅有一个引起它变化的原因。简单来说,一个类中应该是一组相关性很高的函数、数据的封装。就像秦小波老师在《设计模式之禅》中说的:“这是一个备受争议却又极其重要的原则。只要你想和别人争执、怄气或者是吵架,这个原则是屡试不爽的”。因为单一职责的划分界限,并不是总是那么清晰,很多时候都是需要靠个人经验来界定。当然,最大的问题就是对职责的定义,什么是类的职责,以及怎么划分类的职责。

    如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会消弱或者抑制这个类完成其他职责的能力。
    这种耦合会导致脆弱的设置,当变化发生时,设计会遭到意象不到的破坏。

    开放-封闭原则

    开闭原则的英文全称是Open Close Principle,缩写是OCP,它是Java世界里最基础的设计原则,它指导我们如何建立一个稳定的,灵活的系统。

    定义:
    软件中的对象(类、模块、函数等)

    • 对于扩展是开放的
    • 对于更改是封闭的

    开放-封闭原则是面向对象设计的核心所在。遵循这个原则可以带来面向对象技术所声称的巨大好处,也就是可维护、可扩张、可复用、灵活性好。开发人员应该仅对程序中呈现出频繁变化的那些部分做出抽象,然而,对于应用程序中的每个部分都刻意地进行抽象同样不是一个好主意。拒绝不成熟的抽象和抽象本身一样重要。

    里氏替换原则

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

    LSP的第一种定义是:

    如果对每一个类型为S的对象O1,都有类型为T的对象O2,使得以T定义的所有程序P在所有的对象O1都代替成O2时,程序P的行为没有发生变化,那么类型S是类型T的子类型。

    LSP的第二种定义是:

    所有引用基类的地方必须能透明地使用其子类的对象。

    简单的来说,一个软件实体如果使用的是一个父类的话,那么一定适用于其子类,而且它察觉不出来父类对象和子类对象的区别。也就是说,在软件里面,把父类都替换成它的子类,程序行为没有变化。简单的说,子类类型必须能够替换它们的父类型。

    Question.

    在面向对象设计时,一个是鸟类,一个是企鹅类,如果鸟是可以飞的,企鹅不会飞,那么企鹅是鸟吗?企鹅可以继承鸟这个类吗?

    Answer:

    面向对象设计中,子类拥有父类非private的行为和属性,鸟会飞,而企鹅不会飞。尽管在生物学上分类,企鹅是一种鸟,但是在编程世界里,企鹅不能以父类-鸟的身份出现。
    因为前提说所有的鸟都能飞,而企鹅飞不了,所以不能继承鸟类。

    依赖倒置原则

    依赖倒置原则英文全称是:Dependence Inversion Principle,缩写是DIP

    关键点:

    • 高层模块不应该依赖底层模块。两个都应该依赖抽象
    • 抽象不应该依赖细节
    • 细节应该依赖抽象

    依赖倒置其实可以说是面向对象设计的标志,用哪种语言来编写程序不重要,如果编写时考虑的都是如何针对抽象编程而不是针对细节编程,即程序中所有的依赖关系都是终止于抽象类或者接口,那就是面向对象的设计,反之就是过程化的设计了。

    依赖倒置原则在Java语言中的表现就是:模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的。

    接口隔离原则

    接口隔离原则英文全称是:Interface Segregation Principle,缩写是ISP

    ISP的定义是:
    客户端不应该依赖它不需要的接口。

    另一种的定义是:
    类间的依赖关系应该建立在最小的接口上。

    接口隔离原则将非常庞大、臃肿的接口拆分成更小的和更具体的接口,这样客户将会只需要知道他们那感兴趣的方法。接口隔离原则的目的是系统解开耦合,从而容易重构、更改和重新部署。

    Bob大叔(Robert C Martin)在21世纪早期将单一职责、开闭原则、里氏替换、接口隔离以及依赖倒置(也称依赖反转)5个原则,定义为SOLID原则,作为面向对象编程的5个基本原则。

    迪米特原则

    迪米特原则英文全称为Law of Demeter,缩写是LOD,也称为最少知识原则(Least Knowledge Principle)。
    一个对象应该比对其他对象有最少的了解。简单的来说,一个类应该对自己需要耦合或调用的类知识知道得最少,类的内部结构如何实现与调用者或者依赖者没有关系,调用者或者依赖者只需要知道它需要的方法即可,其他的可一概不用管。类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。

    代码:

    售楼中心

    package com.design.pattern.demeter;
    
    import java.util.ArrayList;
    import java.util.Random;
    
    public class BuildingCenter {
    
        private ArrayList<House> mHouses = new ArrayList<House>();
    
        public BuildingCenter() {
        }
    
        /**
         * 初始化房源
         */
        public void addHouse() {
            Random random = new Random();
            for (int index = 0; index < 10; index++) {
                mHouses.add(new House(random.nextInt(10) + "栋", random.nextInt(100) + 100, random.nextInt(20) + 100));
            }
        }
    
        /**
         * 卖房子
         * @param location
         * @param price
         * @param area
         * @return
         */
        public House sellHouse(String location, int price, int area) {
            for (House house : mHouses) {
                if (isSuitHouse(location, price, area, house)) {
                    return house;
                }
            }
            return null;
        }
    
        /**
         * 是否合适
         * @param location
         * @param price
         * @param area
         * @param house
         * @return
         */
        private boolean isSuitHouse(String location, int price, int area, House house) {
            if (house.getLocation().equals(location)) {
                if (house.getPrice() <= price && house.getArea() >= area) {
                    return true;
                }
            }
            return false;
        }
    }
    
    

    房源

    package com.design.pattern.demeter;
    
    public class House {
    
        private String location;
        private int price;
        private int area;
    
        public House(String location, int price, int area) {
            super();
            this.location = location;
            this.price = price;
            this.area = area;
        }
    
        public String getLocation() {
            return location;
        }
    
        public float getPrice() {
            return price;
        }
    
        public float getArea() {
            return area;
        }
    
        @Override
        public String toString() {
            return "House [location=" + location + ", price=" + price + ", area=" + area + "]";
        }
    
    }
    

    买房人

    package com.design.pattern.demeter;
    
    public class Buyer {
    
        /**
         * 买房子
         * @param location
         * @param price
         * @param area
         * @param buildingCenter
         */
        public void buyHouse(String location, int price, int area, BuildingCenter buildingCenter) {
            House house = buildingCenter.sellHouse(location, price, area);
            if (house != null) {
                System.out.println("买到房子了:" + house.toString());
            } else {
                System.out.println("没有合适的房子!");
            }
        }
    }
    
    

    测试结果

    package com.design.pattern.demeter;
    
    public class TestResult {
    
        public static void main(String[] args) {
            BuildingCenter buildingCenter = new BuildingCenter();
            buildingCenter.addHouse();
            Buyer buyer = new Buyer();
            buyer.buyHouse("6栋", 150, 90, buildingCenter);
        }
    
    }
    
    

    Github地址:

    DesignPatterns:https://github.com/EricWinner/DesignPatterns.git

    有任何问题,欢迎指出.

    相关文章

      网友评论

          本文标题:设计原则

          本文链接:https://www.haomeiwen.com/subject/hzkanftx.html