IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 关于Java中软件设计原则 -> 正文阅读

[Java知识库]关于Java中软件设计原则

对于Java中常用的设计模式, 规定了其设计原则,为了提高软件系统的可维护性和可复用性,增加软件的可扩展性和灵活性,我们要尽量根据6条原则来开发程序,从而提高软件开发效率、节约软件开发成本和维护成本

1 开闭原则

对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果.

因为抽象灵活性好, 我们以接口和抽象类实现案例效果.

1 案例

以搜狗输入法的皮肤替换为例, 搜狗输入法有默认的皮肤,也能用户自定义皮肤.首先需要定义一个皮肤抽象类,让二者继承.

1 抽象皮肤类

public abstract class AbstractSkin {
    public abstract void display();
}

2 默认皮肤类

public class DefaultSkin extends AbstractSkin {
    @Override
    public void display() {
        System.out.println("默认皮肤");
    }
}

3 自定义皮肤类

public class CustomSkin extends AbstractSkin {
    @Override
    public void display() {
        System.out.println("自定义皮肤");
    }
}

4 搜狗拼音类

public class SougouInput {

    private AbstractSkin skin;

    public void setSkin(AbstractSkin skin) {
        this.skin = skin;
    }

    public void display() {
        skin.display();
    }
}

5 测试类

public class Client {
    public static void main(String[] args) {
        // 1 创建输入法对象
        SougouInput sougouInput = new SougouInput();
        // 2 创建皮肤对象
//        DefaultSkin skin = new DefaultSkin();
        CustomSkin skin = new CustomSkin();

        // 3 设计默认皮肤
        sougouInput.setSkin(skin);

        // 4 查看皮肤
        sougouInput.display();
    }
}

6 结果

// 第一次 默认皮肤
// 第二次 自定义皮肤

通过接口和抽象类,实现了搜狗拼音的皮肤切换,当后续出现其他皮肤类型,只需要创建一个实现类即可

2 里氏替换原则

里氏代换原则:任何基类可以出现的地方,子类一定可以出现。通俗理解:子类可以扩展父类的功能,但不能改变父类原有的功能.

1 案例

以正方形和长方形为例, 因为正方形属于特殊的长方形. 所以首先创建一个长方形类,再创建一个正方形类继承长方形类.

1 长方形类

public class Rectangle {

    private double length;
    private double width;

    public double getLength() {
        return length;
    }

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

    public double getWidth() {
        return width;
    }

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

2 正方形类

public class Square extends Rectangle {
    @Override
    public void setLength(double length) {
        super.setLength(length);
        super.setWidth(length);

    }

    @Override
    public void setWidth(double width) {
        super.setWidth(width);
        super.setLength(width);
    }
}

3 测试类

    public static void main(String[] args) {
        Rectangle rectangle = new Rectangle();
        // 设置长高
        rectangle.setLength(20);
        rectangle.setWidth(10);
        printLengthAndWidth(rectangle);
        System.out.println("-------------");

        Square square = new Square();
        square.setLength(10);
        resize(square);
        printLengthAndWidth(square);
    }

    public static void resize(Rectangle rectangle) {
        while (rectangle.getLength() <= rectangle.getWidth()) {
            rectangle.setWidth(rectangle.getWidth() + 1);
        }
    }

    public static void printLengthAndWidth(Rectangle rectangle) {
        System.out.println(rectangle.getLength());
        System.out.println(rectangle.getWidth());
    }

}

4 结果

20.0
10.0
-------------
程序一直再循环运行 正方形的长和宽一直再增加...

2 案列改造

1 创建四方形接口

public interface Quadrilateral {

    double getLength();

    double getWidth();
}

2 创建长方形类

public class Rectangle implements Quadrilateral {
    
    private double length;
    private double width;

    @Override
    public double getLength() {
        return length;
    }

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

    @Override
    public double getWidth() {
        return width;
    }

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

3 正方形类

public class Square implements Quadrilateral {

    private double side;

    public void setSide(double side) {
        this.side = side;
    }

    public void setLength(double length) {
        side = length;
    }

    @Override
    public double getLength() {
        return side;
    }
    @Override
    public double getWidth() {
        return side;
    }

4 测试类

    public static void main(String[] args) {
        Rectangle rectangle = new Rectangle();
        // 设置长高
        rectangle.setLength(20);
        rectangle.setWidth(10);
        printLengthAndWidth(rectangle);
        System.out.println("-------------");

        Square square = new Square();
        square.setLength(10);
        printLengthAndWidth(square);

        // 不能传递正方形到热size方法
    }

    public static void resize(Rectangle rectangle) {
        while (rectangle.getLength() <= rectangle.getWidth()) {
            rectangle.setWidth(rectangle.getWidth() + 1);
        }
    }

    public static void printLengthAndWidth(Quadrilateral quadrilateral) {
        System.out.println(quadrilateral.getLength());
        System.out.println(quadrilateral.getWidth());
    }

}

5 结果

20.0
10.0
-------------
10.0
10.0

3 依赖倒转原则

高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象.

1 案例

以电脑类为例. 一个电脑需要基本的cpu,硬盘,内存条.

1 电脑类

public class Computer {

    private XiJieHardDisk hardDisk;
    private IntelCpu cpu;
    private KingstonMemory memory;

    public IntelCpu getCpu() {
        return cpu;
    }

    public void setCpu(IntelCpu cpu) {
        this.cpu = cpu;
    }

    public KingstonMemory getMemory() {
        return memory;
    }

    public void setMemory(KingstonMemory memory) {
        this.memory = memory;
    }

    public XiJieHardDisk getHardDisk() {
        return hardDisk;
    }

    public void setHardDisk(XiJieHardDisk hardDisk) {
        this.hardDisk = hardDisk;
    }

    public void run() {
        System.out.println("计算机工作");
        cpu.run();
        memory.save();
        String data = hardDisk.get();
        System.out.println("从硬盘中获取的数据为:" + data);
    }
}

2 希捷硬盘类

public class XiJieHardDisk {

    public void save(String data) {
        System.out.println("使用希捷硬盘存储数据" + data);
    }

    public String get() {
        System.out.println("使用希捷希捷硬盘取数据");
        return "数据";
    }
}

3 Intel处理器类

public class IntelCpu {

    public void run() {
        System.out.println("使用Intel处理器");
    }
}

4 金士顿内存条类

public class KingstonMemory {

    public void save() {
        System.out.println("使用金士顿作为内存条");
    }
}

5 测试类

public class Client {
    public static void main(String[] args) {
        Computer computer = new Computer();
        computer.setHardDisk(new XiJieHardDisk());
        computer.setCpu(new IntelCpu());
        computer.setMemory(new KingstonMemory());

        computer.run();
    }
}

6 运行结果

计算机工作
使用Intel处理器
使用金士顿作为内存条
使用希捷希捷硬盘取数据
从硬盘中获取的数据为:数据

上述电脑,相关配件已经固定,如果想要换成AMD的cpu或其他品牌的内存条等就不行了.

2 案例改造

1 电脑类

public class Computer {

    private HardDisk hardDisk;
    private Cpu cpu;
    private Memory memory;

    public Cpu getCpu() {
        return cpu;
    }

    public void setCpu(Cpu cpu) {
        this.cpu = cpu;
    }

    public Memory getMemory() {
        return memory;
    }

    public void setMemory(Memory memory) {
        this.memory = memory;
    }

    public HardDisk getHardDisk() {
        return hardDisk;
    }

    public void setHardDisk(HardDisk hardDisk) {
        this.hardDisk = hardDisk;
    }

    public void run() {
        System.out.println("计算机工作");
        cpu.run();
        memory.save();
        String data = hardDisk.get();
        System.out.println("从硬盘中获取的数据为:" + data);
    }
}

2 希捷硬盘类

public class XiJieHardDisk implements HardDisk {

    public void save(String data) {
        System.out.println("使用希捷硬盘存储数据" + data);
    }

    public String get() {
        System.out.println("使用希捷希捷硬盘取数据");
        return "数据";
    }
}

3 AMD处理器类

public class IntelCpu implements Cpu {

    public void run() {
        System.out.println("使用AMD处理器");
    }
}

4 金士顿内存条

public class KingstonMemory implements Memory {

    public void save() {
        System.out.println("使用金士顿作为内存条");
    }
}

5 测试类

public class Client {
    public static void main(String[] args) {
        Computer computer = new Computer();
        computer.setHardDisk(new XiJieHardDisk());
        // computer.setCpu(new IntelCpu());
        computer.setCpu(new AMDCpu());
        computer.setMemory(new KingstonMemory());

        computer.run();
    }
}

6 结果

计算机工作
使用AMD处理器
使用金士顿作为内存条
使用希捷希捷硬盘取数据
从硬盘中获取的数据为:数据

根据依赖倒转原则 , 我们只需要修改Computer类,让Computer类依赖抽象(各个配件的接口),而不是依赖于各个组件具体的实现类即可.

4 接口隔离原则

客户端不应该被迫依赖于它不使用的方法;一个类对另一个类的依赖应该建立在最小的接口上.

1 案例

以安全门为例,安全门有防水防盗的功能, 小牛牌安全门具备上述所有功能

1 安全门接口

public interface SafeDoor {
	void antiTheft();
    void fireproof();
    void waterproof();
}

2 小牛牌

public class XiaoNiuDoor implements SafeDoor {
      @Override
    public void antiTheft() {
       
    }
        @Override
    public void fireproof() {
       
    }
        @Override
    public void fireproof() {
       
    }
}

此时,出现了一个小狗牌,他只能防水防盗,没有防火功能,就不好处理

2 案例改造

1 防盗接口

public interface AntiTheft {
    void antiTheft();
}

2 防火接口

public interface Fireproof {
    void fireproof();
}

3 防水接口

public interface Waterproof {
    void waterproof();
}

4 小狗牌

public class XiaoGouDoor implements AntiTheft, Waterproof{
      @Override
    public void antiTheft() {
       
    }
        @Override
    public void fireproof() {
       
    }
}

将所有功能分开到不同的接口中,类需要那种功能就实现那种接口.

5 迪米特法则

迪米特法则又叫最少知识原则. 如果两个实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用.

1 案例

以 明星,经纪人,粉丝,广告公司之间为例, 明星和粉丝见面由经纪人安排,明星和广告公司合作由经纪人安排,所以通过经纪人将三者关联.

1 明星类

public class Star {
    private String name;

    public Star(String name) {
        this.name=name;
    }

    public String getName() {
        return name;
    }
}

2 粉丝类

public class Fans {
    private String name;

    public Fans(String name) {
        this.name=name;
    }

    public String getName() {
        return name;
    }
}

3 广告公司类

public class Company {
    private String name;

    public Company(String name) {
        this.name=name;
    }

    public String getName() {
        return name;
    }
}

4 经纪人类

public class Agent {
    private Star star;
    private Fans fans;
    private Company company;

    public void setStar(Star star) {
        this.star = star;
    }

    public void setFans(Fans fans) {
        this.fans = fans;
    }

    public void setCompany(Company company) {
        this.company = company;
    }

    public void meeting() {
        System.out.println(fans.getName() + "与明星" + star.getName() + "见面了。");
    }

    public void business() {
        System.out.println(company.getName() + "与明星" + star.getName() + "商谈业务。");
    }
}

通过经纪人, 将明星和粉丝, 公告公司关联起来,实现最少关联.

6 合成复用原则

合成复用原则是指:尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现.

1 案例

以汽车分类划分, 车按照动力分,汽油车,电动车; 按照颜色分,红车,白车.

1 按照继承关系来划分

1 汽车类
public class Car {
    public void move(){
    }
}
2 油车
public class PetroCar extends  Car{
    @Override
    public void move() {
        super.move();
    }
}
3 红色油车
public class RedPetroCar extends  PetroCar{
    @Override
    public void move() {
        super.move();
    }
}
4 白色油车
public class WhitePetroCar extends  PetroCar{
    @Override
    public void move() {
        super.move();
    }
}
5 电车
public class EleCar extends Car {
    @Override
    public void move() {
        super.move();
    }
}
6 红色电车
public class RedEleCar extends Car {
    @Override
    public void move() {
        super.move();
    }
}
7 白色电车
public class WhiteEleCar extends EleCar  {
    @Override
    public void move() {
        super.move();
    }
}

如果出现新的氢能源车 ,又得新增三个类.

2 按照聚合复用关系来划分

把颜色抽象成接口,聚合复用到汽车类中.

1 颜色接口
public interface Color {
}
2 汽车类
public class Car {
    private Color color;
    public void move(){

    }

}

然后油车, 电车可以传入不同的颜色,构造出不同颜色的车型. 如果新增氢能源车,也只需要新增一个类即可.

所以, 在类机构设计时尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-27 11:11:09  更:2022-04-27 11:12:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:26:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码