Java基础——设计原则

1.概述

设计模式,不是一种新的语言,也不是什么新的API,也不是什么新的语法
设计模式,是前辈们,不断总结,不断打磨出的一种经验的总结,不同的设计模式适用不同的场景。
设计模式,公认的有23种设计模式,分别对应不同的场景,这些设计模式是经过长期实践总结而留存下来的。
千万不要认为有任何一种设计模式,能够解决任何问题。每一种设计模式只能用于使用的场景。而不是万能的。
设计模式有优点也有缺点。我们不要为了适用设计模式而使用设计模式,切记设计模式的滥用,
23中设计模式的背后,其实是7大设计原则,也就是说每个设计模式都归属于一个或多个设计原则。

2.设计原则

面向对象思想设计原则

在实际的开发中,我们要想更深入的了解面向对象思想,就必须熟悉前人总结过的面向对象的思想的设计原则

单一职能原则

开闭原则

里氏替换原则

依赖倒置原则

接口分离原则

迪米特原则

3.单一职能原则

单一职责原则

其实就是开发人员经常说的”高内聚,低耦合”

也就是说,每个类或每个方法都只负责一件事情。

在设计模式中,所有的设计模式都遵循这一原则

需求:统计文本文件中有多少个单词
比如:我们有一个文本文件内容如下:
hello world
how are you

public class postive {
    
    public static StringBuilder loadFile(String fileLocation) throws IOException {
      
            //读取文件的内容
            Reader in = new FileReader("E:\\1.txt");
            BufferedReader bufferedReader = new BufferedReader(in);

            String line = null;
            StringBuilder sb = new StringBuilder("");

            while ((line = bufferedReader.readLine()) != null) {
                sb.append(line);
                sb.append(" ");
            }
            
            bufferedReader.close();
            return sb;
    }
    
    public static String[] getWords(String regex, StringBuilder sb){
        //对内容进行分割
        return  sb.toString().split(regex);
    }
    
    public static void main(String[] args) throws IOException {
        
            //读取文件的内容
            StringBuilder sb = loadFile("E:\\1.txt");
            
            //对内容进行分割
            String[] words = getWords("[^a-zA-Z]+", sb);
            
            System.out.println(words.length);
    }
}

遵守单一原则,可以给我们带来的好处是,提高了代码的可重用性,同时还让得到的数据不再有耦合,可以用来完成我们的个性化需求。

4.开闭原则

开闭原则
核心思想是:一个对象对扩展开放,对修改关闭。
其实开闭原则的意思就是:对类的改动是通过增加代码进行的,而不是修改现有代码。
也就是说软件开发人员一旦写出了可以运行的代码,就不应该去改动它,而是要保证它能一直运行下去,如何能够做到这一点呢?这就需要借助于抽象和多态,即把可能变化的内容抽象出来,从而使抽象的部分是相对稳定的,而具体的实现则是可以改变和扩展的。
举例


定义一个Carpublic class Car {
    private String name;
    private String color;
    private float price;
    //get set 方法略
 }   
 
public class MyTest {
    public static void main(String[] args) {
        Car car = new Car();
        car.setName("奔驰");
        car.setColor("白色");
        car.setPrice(99999);
    }
}

//我们定义一个类去继承Car 然后做价格的调整

public class BenzCar extends Car {
    @Override
    public void setPrice(double price) {
        super.setPrice(price * 0.8);
    }
}

5. 接口隔离原则

核心思想:不应该强迫程序依赖它们不需要使用的方法。

其实就是说:一个接口不需要提供太多的行为,一个接口应该只提供一种对外的功能,不应该把所有的操作都封装到一个接口中。

6.依赖倒置原则

上层不能依赖于下层。

他们都应该依赖于抽象。

class Person {
    public void feed(Animal an) {
        System.out.println("开始喂养");
        an.eat();
    }
}
abstract class Animal{
    public abstract void eat();
}
class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
}

class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃小鱼干");
    }
}

public class MyTest {
    public static void main(String[] args) {
        Person person = new Person();
        Dog dog = new Dog();
        Cat cat = new Cat();
        person.feed(dog);
        person.feed(cat);
    }
}

现在我们的上层Person只依赖于Animal

下层的改动,不在影响上层

7.迪米特原则(最少知道原则)

核心思想:一个类应当对其他类知道的越少越好。

只和朋友通信。

什么是朋友?

1.类中的字段是朋友

2.方法的参数是朋友

3.方法的返回值是朋友

4.方法中实例化出来的对象是朋友

//私有关机的四个方法,对外暴露一个公共的关机方法

class Computer {
    private void saveData() {
        System.out.println("保存数据...");
    }

    private void killProcess() {
        System.out.println("关闭程序");
    }

    private void closeScreen() {
        System.out.println("关闭屏幕");
    }

    private void powerOff() {
        System.out.println("关闭电源");
    }
    public void shutdownOff(){
        saveData();
        killProcess();
        closeScreen();
        powerOff();
    }
}

class Person {
    Computer computer = new Computer();

    public void shutdown() {
       computer.shutdownOff();
    }
}

public class MyTest {
    public static void main(String[] args) {

    }
}

 public String show(Integer number){
        int i = number.intValue();
        String s = new String("abcdef");
         s.substring(0);
         s.contains("a");
         return s;
    }
  //比如:上面的这个方法,有形参 Integer 类 有方法中创建出的 String类,那他们就都是朋友
  //你就可以调用Integer 类和 String 类中的任何方法,而不必担心知道的太多。

8. 里氏替换原则

里氏替换原则

核心思想:在任何父类出现的地方都可以用它的子类来替代。

其实就是说:子类可以随时随地替换父类对象,且替换完之后,语法不会报错,业务逻辑也不会出现问题。

需求:将长方形的宽改成比长大 1

//正常情况下
class Rectangular {
    private Integer width; //宽
    private Integer length; //长

    public Integer getWidth() {
        return width;
    }

    public void setWidth(Integer width) {
        this.width = width;
    }

    public Integer getLength() {
        return length;
    }

    public void setLength(Integer length) {
        this.length = length;
    }

    //计算面积的方法
    public double getArea() {
        return length * width;
    }
}

//定义一个正方形的类,继承长方形
class Square extends Rectangular {
    private Integer sideWidth;//边长

    @Override
    public Integer getWidth() {
        return sideWidth;
    }

    @Override
    public void setWidth(Integer width) {
        this.sideWidth = width;
    }

    @Override
    public Integer getLength() {
        return sideWidth;
    }

    @Override
    public void setLength(Integer length) {
        this.sideWidth = length;
    }

    @Override
    public double getArea() {
        return sideWidth * sideWidth;
    }
}

public class MyTest {
    public static void main(String[] args) {
        Rectangular rectangular = new Rectangular();
        //这里可以替换成子类
                    rectangular = new Square();
        rectangular.setWidth(20);
        rectangular.setLength(15);
        double area = rectangular.getArea();
        System.out.println(area);
        System.out.println("==============================");
    }
}

看特殊情况

class Utils {
    public static void transform(Rectangular graph) {
        //如果宽小于等于长,就让宽加1
        while (graph.getWidth() <= graph.getLength()) {
            graph.setWidth(graph.getWidth() + 1);
            System.out.println("长:" + graph.getLength() + " : " +
                    "宽:" + graph.getWidth());
        }
    }
}
public class MyTest {
    public static void main(String[] args) {
        Rectangular rectangular = new Rectangular();
        //这里可以替换成子类,
        //rectangular = new Square();
        rectangular.setWidth(20);
        rectangular.setLength(150);
        System.out.println("==============================");
        //传入长方形的对象,没有问题,但是传入正方形就有问题了,成死循环了。
        Utils.transform(rectangular);
    }
}

//这里父类就不能用子类对象来替换了,替换之后,会发生问题
//要知道,在向上转型的时候,方法的调用只和new的对象有关,才会造成不同的结果。在使用场景下,需要考虑替换后业务逻辑是否受影响。
//由此引出里氏替换原则的使用需要考虑的条件:
   // 是否有is-a关系
   // 子类可以扩展父类的功能,但是不能改变父类原有的功能。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Geek Li

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值