java设计模式六大原则

java设计模式六大原则

说到设计模式,它不是一种新的语言,也不是新的API,也不是新的语法,
设计模式,是前辈们,不断总结,不断打磨出得一种经验的总结,不同的设计模式适用不同的场景。
设计模式,公认的有23种,分别对应不同的场景,千万不要认为有任何一种设计模式,能够解决任何问题,每一种设计
模式只能用于使用的场景,而不是万能的。
23种设计模式的背后,其实是六大原则,也就是说每一个设计模式都归属于一个或多个设计原则。
设计原则
面向对象思想设计原则:
1.单一职能原则
2.开闭原则
3.接口分离原则
4.依赖倒置原则
5.迪米特原则
6.里氏替换原则
单一职能原则
	其实就是开发人员常说的“高内聚,低耦合”,也就是说,每个类或每个方法都只负责一件事情。
好处就是:遵循单一职能原则,提高了代码的可重用性,同时还让得到的数据不再耦合,可以用来完成我们的个性化需求。
//文本文件里的内容
//hello world
//how are you
public class MyTest {
    public static void main(String[] args) throws IOException {
        //统计文本文件中的单词
        FileReader fileReader = new FileReader("1.txt");
        BufferedReader reader = new BufferedReader(fileReader);
        StringBuilder sb = new StringBuilder("");
        String line=null;
        //读取文件中的信息,将信息加入到StringBuilder里
        while ((line=reader.readLine())!=null){
            sb.append(line);
            sb.append(" ");
        }
        //用正则表达式将单词分割到数组中
        String[] strings = sb.toString().split(" ");
        //打印数组
        System.out.println(Arrays.toString(strings));
        reader.close();
    }
}
//上面的代码就违反了单一职能原则,同一个方法我们让它去做文件读取,还让它做内容分割;当有需求变更(需要更换加载文件,统计文本文件中有多少个句子)时,我们需要重写整个方法。
打印结果

在这里插入图片描述

开闭原则
开闭原则核心思想是:一个对象对外扩展开放,对修改关闭
其实开闭原则的意思就是:对类的改动是通过增加代码进行的,而不是修改现有的代码。
也就是说软件开发人员一旦写出了可以运行的代码,就不应该去改动它,而是要保证它能一直运行下去,
这就需要借助抽象和多态,即把可能变化的内容抽象出来,从而使抽象的部分是相对稳定的,而具体的实现则是可以
改变和扩展的。
//需求:商品搞活动,打8折优惠
public class Car {
    private String name;
    private String color;
    private float price;
    public Car() {
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
    public float getPrice() {
        return price;
    }
    public void setPrice(float price) {
        this.price = price*0.8;        //直接在源码中修改,这就违反了开闭原则,
    }
}
public class MyTest {
    public static void main(String[] args) {
        Car car = new Car();
        car.setName("奔驰");
        car.setColor("白色");
        car.setPrice(99999);
    }
}
//我们在开发时,必须考虑可能会变化的需求,属性在任何时候都可能发生改变,对于需求的变化,在要求遵循开闭原则
//的前提下,我们应该在开发中去进行扩展,而不是修改源码
public class BenzCar extends Car{
    @Override
    public void setPrice(float price) {
        super.setPrice((float) (price*0.8));
    }
}
//所以我们定义一个类去继承Car,然后做价格的调整就行了。
接口隔离原则
核心思想:不应该强迫程序依赖它们不需要使用的方法
其实就是说:一个接口不需要提供太多的行为,一个接口应该只提供一种对外的功能,不应该把所有的操作都封装到一个
接口中。
依赖倒置原则
核心思想:上层不能依赖于下层
		他们都应该依赖于抽象
上层:调用别的方法的,就是上层
下层:被其他方法调用的就是下层
public class MyTest3 {
    public static void main(String[] args) {
        Person person = new Person();
        Dog dog = new Dog();
        person.feed(dog);
    }
}
class Person{
    public void feed(Dog dog){
        System.out.println("开始喂养");
        dog.eat();
    }
}
class Dog{
    public void eat(){
        System.out.println("吃骨头");
    }
}
//现在需求增加了还需要喂养小猫
//这时就需要在Person中提供一个重载方法
public class MyTest3 {
    public static void main(String[] args) {
        Person person = new Person();
        Dog dog = new Dog();
        Cat cat = new Cat();
        person.feed(dog);
        person.feed(cat);
    }
}
class Person{
    public void feed(Dog dog){
        System.out.println("开始喂养");
        dog.eat();
    }
    public void feed(Cat cat){
        System.out.println("开始喂养");
        cat.eat();
    }
}
class Dog{
    public void eat(){
        System.out.println("吃骨头");
    }
}
class Cat{
    public void eat(){
        System.out.println("吃小鱼干");
    }
}
//也就是说,我们每增加一个动物,都需要在Person类中提供一个重载方法
//那现在就是 上层依赖于下层 也就是Person类依赖于Dog类、Cat类
//那么下层每增加一个类,就得去修改上层,违反了依赖倒置,也就是下层一变化,上层也跟着变
//我们希望的是,当下层增加一个类时,上层应该不知道,也就是上层不应该发生变动。
public class MyTest3 {
    public static void main(String[] args) {
        Person person = new Person();
        Dog dog = new Dog();
        Cat cat = new Cat();
        person.feed(dog);
        person.feed(cat);
    }
}
class Person{
    public void feed(Animal animal){
        System.out.println("开始喂养");
        animal.eat();
    }
}
//定义一个抽象动物父类,让它们都去继承这个父类,去重写eat()方法,这样每增加一个类,
//Person类就不需要再提供一个重载方法了,符合依赖倒置原则
abstract class Animal{
    public abstract void eat();
}
class Dog extends Animal{
    public void eat(){
        System.out.println("吃骨头");
    }
}
class Cat extends Animal{
    public void eat(){
        System.out.println("吃小鱼干");
    }
}
迪米特原则
核心思想:一个类应当对其他类知道的越少越好
就是只和朋友通信
朋友就是:1.类中的字段是朋友
		2.方法的参数是朋友
		3.方法的返回值是朋友
		4.方法中实例化出来的对象是朋友
public class MyTest4 {
    public static void main(String[] args) {
        Person person = new Person();
        person.shutdownOff();
    }
}
class Computer{
    private void saveData(){
        System.out.println("保存数据....");
    }
    private void killProcess(){
        System.out.println("关闭程序....");
    }
    private void closeSeen(){
        System.out.println("关闭屏幕....");
    }
    private void powerOff(){
        System.out.println("关闭电源....");
    }
    public void shutdownOff(){
        saveData();
        killProcess();
        closeSeen();
        powerOff();
    }
}
class Person{
    Computer computer=new Computer();
    public void shutdownOff(){
        computer.shutdownOff();
    }
}
	上面代码中就符合迪米特原则,对于Person类而言,不需要知道如何保存数据,关闭程序,关闭屏幕,关闭电源,只需要知道关机按钮就行了。
	迪米特原则的实现方法的特点:
	1.从依赖者的角度来说,只依赖应该依赖的对象。
	2.从被依赖者的角度来说,只暴露应该暴露的方法。
里氏替换原则
核心思想: 在任何父类出现的地方都可以用它的子类来替代
其实就是说:子类可以随时随地替换父类对象,且替换完之后,语法不会报错,业务逻辑也不会出现问题
public class MyTest {
    public static void main(String[] args) {
        Rectangular rectangular = new Rectangular();
        //rectangular=new Square();     这里可以替换成子类
        rectangular.setLength(150);
        rectangular.setWidth(20);
        System.out.println("==================");
        Utils.transform(rectangular);
    }
}
class Rectangular{    //定义一个长方形类
    private int length;   //长
    private int width;     //宽
    public int getLength() {
        return length;
    }
    public void setLength(int length) {
        this.length = length;
    }
    public int getWidth() {
        return width;
    }
    public void setWidth(int width) {
        this.width = width;
    }
}
class Square extends Rectangular{   //定义一个正方形类并继承长方形类
    private int sideWith;  //边长
    @Override
    public int getLength() {
        return sideWith;
    }
    @Override
    public void setLength(int length) {
        this.sideWith=length;
    }
    @Override
    public int getWidth() {
        return sideWith;
    }
    @Override
    public void setWidth(int width) {
        this.sideWith=sideWith;
    }
}
class Utils{   //定义一个工具类,如果宽小于等于长,宽就加1
    public static void transform(Rectangular graph){
        while(graph.getWidth()<=graph.getLength()){
            graph.setWidth(graph.getWidth()+1);
            System.out.println("长:"+graph.getLength()+";"+"宽:"+graph.getWidth());
        }
    }
}
传入长方形对象的结果在这里插入图片描述
传入正方形对象的结果

在这里插入图片描述

从结果中就可以看出,如果传入的是长方形的对象,程序就没有问题,如果传入的是正方形就有问题了,代码就会出现死
循环。这里父类就不能用子类对象来替换了,替换后,会发生问题。
要知道,在向上转型的时候,方法的调用只和new的对象有关,才会造成不同的结果。在使用场景下,需要考虑替换业务
逻辑是否受影响。
由此可以引出里氏替换原则的使用需要考虑的条件:
	是否是is-a关系
	子类可以扩展父类的功能,但是不能改变父类原有的功能
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值