设计模式第一回

一 UML

1.1 UML Class

1.1 子类指向父类

设计模式第一回_第1张图片

1.2 实现继承、虚线实现

设计模式第一回_第2张图片

设计模式第一回_第3张图片

1.3 实现关联,虚线依赖

设计模式第一回_第4张图片

设计模式第一回_第5张图片

虚线:
设计模式第一回_第6张图片

实线:
设计模式第一回_第7张图片

1.4 空心菱形-聚合 实心菱形-组合

设计模式第一回_第8张图片

设计模式第一回_第9张图片

设计模式第一回_第10张图片

设计模式第一回_第11张图片

设计模式第一回_第12张图片

设计模式第一回_第13张图片

1.5 案例

设计模式第一回_第14张图片

1.2 UML时序图

设计模式第一回_第15张图片

设计模式第一回_第16张图片

二 设计原则

设计原则:

  • 开闭原则

  • 依赖倒置原则

  • 单一职责原则

  • 接口隔离原则

  • 迪米特法则(最少知道原则)

  • 里氏替换原则

  • 合成、复用原则(组合、复用原则)

    2.1 开闭原则

    一个软件实体如类,模块或者函数应该对扩展开放,对修改关闭(开闭)。强调的是用抽象构建框架,用实现扩展细节。按照这个原则的优点就是提高软件的可复用性和可维护性。----面向抽象编程。

举例有个课程的设计,面向抽象编程首先课程定义成接口,课程有获取课程id,课程名称,课程价格的三个抽象方法

public interface ICourse {

    public Integer getId();
    public String getName();
    public Double getPrice();

}

针对课程,可能会有Java课程,Go课程,PHP课程等等,因此我们会有不同的子类实现

package designpatterns.principle.openclose;

public class JavaCourse  implements ICourse{

    private int id;
    private String name;
    private double price;

    public JavaCourse(int id, String name, double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }

    @Override
    public Integer getId() {
        return this.id;
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public Double getPrice() {
        return this.price;
    }
}
package designpatterns.principle.openclose;

public class GoCourse implements ICourse{

    private int id;
    private String name;
    private double price;

    public GoCourse(int id, String name, double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }

    @Override
    public Integer getId() {
        return this.id;
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public Double getPrice() {
        return this.price;
    }
}

设计模式第一回_第17张图片

我们编写一个测试类,来获取某个具体课程的名称,价格等:

package designpatterns.principle.openclose;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import static org.junit.Assert.*;

@Slf4j
public class ICourseTest {

    @Test
    public void testCourse() {

        ICourse iCourse = new JavaCourse(1001, "java 编程学习", 320);

        log.info("课程id {}, 课程名称{}, 课程价格{}", iCourse.getId(), iCourse.getName(), iCourse.getPrice());

    }
}

假如这时候这时候我们需要一个活动,比如双十一 618等等,这时候价格有一个打折的价格。那么应该怎么做?

一种方法我们通过修改接口,增加一个getDiscountPrice(), 但是接口一般是稳定的,不应该有大动作改动,这会带来一个问题,就是我们的所有这个接口的实例比如JavaCourse,GoCourse 都需要更改逻辑增加这样的一个方法,这就破坏了我们的开闭原则。那么我们还能怎么做呢?
定义一个新的子类,继承自JavaCourse,这时候我们就不需要改动Course接口,也不需要改动avaCourse,GoCourse,这样我们就做到了对扩展开放,对修改关闭。

package designpatterns.principle.openclose;

public class JavaDiscountCourse  extends JavaCourse{
    public JavaDiscountCourse(int id, String name, double price) {
        super(id, name, price);
    }


    public Double getOriginPrice() {
        return super.getPrice();
    }

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

测试类调整如下:

package designpatterns.principle.openclose;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import static org.junit.Assert.*;

@Slf4j
public class ICourseTest {

    @Test
    public void testCourse() {

        ICourse iCourse = new JavaCourse(1001, "java 编程学习", 320);

        log.info("课程id {}, 课程名称{}, 课程价格{}", iCourse.getId(), iCourse.getName(), iCourse.getPrice());

    }

    @Test
    public void testCourseDiscount() {

        ICourse iCourse = new JavaDiscountCourse(1001, "java 编程学习", 320);

        JavaDiscountCourse javaDiscountCourse = (JavaDiscountCourse)iCourse;
        log.info("课程id {}, 课程名称{}, 原始课程价格{},打折之后的价格", iCourse.getId(), iCourse.getName(), ((JavaDiscountCourse) iCourse).getOriginPrice(), iCourse.getPrice());

    }
}

你可能感兴趣的:(java,设计模式,uml,java)