【设计模式】设计模式导论

前言

代码部分为网络上收集,并根据自己的理解记忆

什么是GOF

在 1994 年, 由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 四人合著出版了名为Design Patterns - Elements of Rausable Object-Oriented Software(中文译名:设计模式-可复用的面对对象软件元素)的书,该书首次提到了软件开发中设计模式的概念。

对接口编程而不是对实现编程。
优先使用对象组合而不是继承。

设计模式的基石

  • 封装
  • 继承
  • 多态

  • 顺序
  • 判断
  • 循环

组件的生命周期

在这里插入图片描述

设计模式的7大原则

开闭原则

  • 软件实体应当对扩展开放,对修改关闭
  • 合成复用原则、里氏替换原则相辅相成,都是开闭原则的具体实现规范。
  • 人话:扩展新类而不是修改旧类。

里氏替换原则

  • 继承必须确保超类所拥有的性质在子类中仍然成立。
  • 人话:继承父类而不去改变父类。

依赖倒置原则

  • 高层模块不应该依赖底层模块,两者都是应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象
  • 人话:面向接口编程,而不是面向实现类

单一职责原则

  • 一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分
  • 人话:每个类只负责自己的事情,而不是变成万能

接口隔离原则

  • 一个类对另一个类的依赖应该建立在最小的接口上
  • 人话:各个类建立自己的专用接口,而不是建立万能接口

迪米特法则

  • 最少知道原则
  • 只与你的直接朋友交谈,不跟 ‘陌生人’ 说话
  • 人话:无需直接交互的两个类,如果需要交互,使用中间者
  • 警:过度使用迪米特法则则会使系统产生大量的中介类,从而增加系统的复杂性,使模块之间的通信效率降低

合成复用原则

  • 又叫组合/聚合复用原则
  • 软件服用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现
  • 人言:优先组合其次继承

代码

开闭原则

扩展新类而不是修改旧类

场景秒速,假设:某教学网站上,出售一个价格888的教学课程,而这个时候做活动,需要将这个课程打折出售,是直接修改呢,还是扩展它呢
在这里插入图片描述

// 课程
public interface ICourse {
    Integer getId();
    String getName();
    Double getPrice();
}
// java课程
public class JavaCourse implements ICourse{
    private Integer Id;
    private String name;
    private Double price;

    public JavaCourse(Integer id, String name, Double price) {
        this.Id = id;
        this.name = name;
        this.price = price;
    }

    public Integer getId() {return this.Id;}
    public String getName() {return this.name;}
    public Double getPrice() {return this.price;}
}
// 打折后的Java课程
public class JavaDiscountCourse extends JavaCourse {

    public JavaDiscountCourse(Integer id, String name, Double price) {
        super(id, name, price);
    }

    public Double getDiscountPrice(){
        return super.getPrice()*0.8;
    }

}
// 测试
public class Test {
    public static void main(String[] args) {
        ICourse iCourse = new JavaDiscountCourse(96, "Java从零到企业级电商开发", 348d);
        JavaDiscountCourse javaCourse = (JavaDiscountCourse) iCourse;

        System.out.println(
                "课程ID:" + javaCourse.getId() +
                " 课程名称:" + javaCourse.getName() +
                " 课程原价:" + javaCourse.getPrice() +
                " 课程折后价格:" + javaCourse.getDiscountPrice() + "元");


    }
}

里氏替换原则

继承父类而不去改变父类


在这里插入图片描述
方法的输入和输出
methodinput

public class Base {
    public void method(HashMap map){
        System.out.println("父类被执行");
    }
}
public class Child extends Base {
//    @Override
//    public void method(HashMap map) {
//        System.out.println("子类HashMap入参方法被执行");
//    }


    public void method(Map map) {
        System.out.println("子类HashMap入参方法被执行");
    }
}
public class Test {
    public static void main(String[] args) {
        Base child = new Child();
        HashMap hashMap = new HashMap();
        child.method(hashMap);
    }
}
// 输出:父类被执行

methodoutput

public abstract class Base {
    public abstract Map method();

}
public class Child extends Base {
    @Override
    public HashMap method() {
        HashMap hashMap = new HashMap();
        System.out.println("子类method被执行");
        hashMap.put("message","子类method被执行");
        return hashMap;
    }
}
public class Test {
    public static void main(String[] args) {
        Child child = new Child();
        System.out.println(child.method());

    }
}

在这里插入图片描述

// 四边形
public interface Quadrangle {
    long getWidth();
    long getLength();

}
// 长方形属于四边形一种
public class Rectangle implements Quadrangle {
    private long length;
    private long width;

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

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

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

    public void setWidth(long width) {
        this.width = width;
    }
}
public class Test {
    public static void resize(Rectangle rectangle){
        while (rectangle.getWidth() <= rectangle.getLength()){
            rectangle.setWidth(rectangle.getWidth()+1);
            System.out.println("width:"+rectangle.getWidth() + " length:"+rectangle.getLength());
        }
        System.out.println("resize方法结束 width:"+rectangle.getWidth() + " length:"+rectangle.getLength());
    }

    public static void main(String[] args) {
        Rectangle rectangle = new Rectangle();
        rectangle.setWidth(10);
        rectangle.setLength(20);
        resize(rectangle);
    }
    }

接口隔离原则

各个类建立自己的专用接口,而不是建立万能接口
场景:
不同动物会的不一样
鸟:吃、飞、游
狗:吃、游
在这里插入图片描述

public class Bird implements IAnimalAction {
    @Override
    public void eat() {}

    @Override
    public void fly() {}

    @Override
    public void swim() {}
}
public class Dog implements ISwimAnimalAction,IEatAnimalAction {

    @Override
    public void eat() {}

    @Override
    public void swim() {}
}
// 吃、飞、游都会
public interface IAnimalAction {
    void eat();
    void fly();
    void swim();

}
// 吃
public interface IEatAnimalAction {
    void eat();
}
// 飞行
public interface IFlyAnimalAction {
    void fly();
}
// 游泳
public interface ISwimAnimalAction {
    void swim();
}

合成复用原则

优先组合其次继承


在这里插入图片描述
场景描述:往不同的数据库中,添加商品数据。

public abstract class DBConnection {
    public abstract String getConnection();
}
public class MySQLConnection extends DBConnection{
    @Override
    public String getConnection() {
        return "MySQL数据库链接";
    }
}
public class PostgreSQLConnection extends DBConnection{
    @Override
    public String getConnection() {
        return "PostgreSQL数据库连接";
    }
}
public class ProductDao {

    private DBConnection dbConnection;

    public void setDbConnection(DBConnection dbConnection) {
        this.dbConnection = dbConnection;
    }

    public void addProduct() {
        String conn = dbConnection.getConnection();
        System.out.println("使用" + conn + "增加产品");
    }
}
public class Test {
    public static void main(String[] args) {
        ProductDao productDao = new ProductDao();
        productDao.setDbConnection(new PostgreSQLConnection());
        productDao.addProduct();
    }
}

迪米特原则

无需要直接交互的两个类,如果需要交互,使用中间者


在这里插入图片描述
场景描述:培训公司有很多课程,该公司老板想确认有多少课程,这时候需要一个中间者(管理者)告诉他,而不是他直接确认

public class Boss {

    public void commandCheckNumber(TeamLeader teamLeader){
        teamLeader.checkNumberOfCourses();
    }

}
public class Course {
}
public class TeamLeader {
    public void checkNumberOfCourses(){
        List<Course> courseList = new ArrayList<Course>();
        for(int i = 0 ;i < 20;i++){
            courseList.add(new Course());
        }
        System.out.println("在线课程的数量是:"+courseList.size());
    }

}
public class Test {
    public static void main(String[] args) {
        Boss boss = new Boss();
        TeamLeader teamLeader = new TeamLeader();
        boss.commandCheckNumber(teamLeader);

    }
}

依赖倒置原则

面向接口编程,而不是实现类


在这里插入图片描述

public class FECourse implements ICourse {
    @Override
    public void studyCourse() {
        System.out.println("Geely在学习FE课程");
    }

}
public class Geely {

    public void setiCourse(ICourse iCourse) {
        this.iCourse = iCourse;
    }

    private ICourse iCourse;
    
    public void studyImoocCourse(){
        iCourse.studyCourse();
    }
    
}
public interface ICourse {
    void studyCourse();
}
public class JavaCourse implements ICourse {

    @Override
    public void studyCourse() {
        System.out.println("Geely在学习Java课程");
    }
}
public class PythonCourse implements ICourse {
    @Override
    public void studyCourse() {
        System.out.println("Geely在学习Python课程");
    }
}
public class Test {

    //v1
//    public static void main(String[] args) {
//        Geely geely = new Geely();
//        geely.studyJavaCourse();
//        geely.studyFECourse();
//    }

    //v2
//    public static void main(String[] args) {
//        Geely geely = new Geely();
//        geely.studyImoocCourse(new JavaCourse());
//        geely.studyImoocCourse(new FECourse());
//        geely.studyImoocCourse(new PythonCourse());
//    }

    //v3
//    public static void main(String[] args) {
//        Geely geely = new Geely(new JavaCourse());
//        geely.studyImoocCourse();
//    }
    public static void main(String[] args) {
        Geely geely = new Geely();
        geely.setiCourse(new JavaCourse());
        geely.studyImoocCourse();

//        geely.setiCourse(new FECourse());
//        geely.studyImoocCourse();

    }


}

单一职责原则

每个类只负责自己的事情,而不是编程万能


public class FlyBird {
    public void mainMoveMode(String birdName){
        System.out.println(birdName+"用翅膀飞");
    }
}
public class WalkBird {
    public void mainMoveMode(String birdName){
        System.out.println(birdName+"用脚走");
    }
}

// 错误例子
public class Bird {
    public void mainMoveMode(String birdName){
        if("鸵鸟".equals(birdName)){
            System.out.println(birdName+"用脚走");
        }else{
            System.out.println(birdName+"用翅膀飞");
        }
    }
}
public class Test {
    public static void main(String[] args) {
//        Bird bird = new Bird();
//        bird.mainMoveMode("大雁");
//        bird.mainMoveMode("鸵鸟");

        FlyBird flyBird = new FlyBird();
        flyBird.mainMoveMode("大雁");

        WalkBird walkBird = new WalkBird();
        walkBird.mainMoveMode("鸵鸟");

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值