一 UML
1.1 UML Class
1.1 子类指向父类
文章图片
1.2 实现继承、虚线实现
文章图片
文章图片
1.3 实现关联,虚线依赖
文章图片
文章图片
虚线:
文章图片
实线:
文章图片
1.4 空心菱形-聚合 实心菱形-组合
文章图片
文章图片
文章图片
文章图片
文章图片
文章图片
1.5 案例
文章图片
1.2 UML时序图
文章图片
文章图片
二 设计原则 设计原则:
- 开闭原则
- 依赖倒置原则
- 单一职责原则
- 接口隔离原则
- 迪米特法则(最少知道原则)
- 里氏替换原则
- 合成、复用原则(组合、复用原则)
2.1 开闭原则 一个软件实体如类,模块或者函数应该对扩展开放,对修改关闭(开闭)。强调的是用抽象构建框架,用实现扩展细节。按照这个原则的优点就是提高软件的可复用性和可维护性。----面向抽象编程。
public interface ICourse {public Integer getId();
public String getName();
public Double getPrice();
}
针对课程,可能会有Java课程,Go课程,PHP课程等等,因此我们会有不同的子类实现
package designpatterns.principle.openclose;
public class JavaCourseimplements 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;
}
}
文章图片
我们编写一个测试类,来获取某个具体课程的名称,价格等:
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等等,这时候价格有一个打折的价格。那么应该怎么做?
【java|设计模式第一回】一种方法我们通过修改接口,增加一个getDiscountPrice(), 但是接口一般是稳定的,不应该有大动作改动,这会带来一个问题,就是我们的所有这个接口的实例比如JavaCourse,GoCourse 都需要更改逻辑增加这样的一个方法,这就破坏了我们的开闭原则。那么我们还能怎么做呢?
定义一个新的子类,继承自JavaCourse,这时候我们就不需要改动Course接口,也不需要改动avaCourse,GoCourse,这样我们就做到了对扩展开放,对修改关闭。
package designpatterns.principle.openclose;
public class JavaDiscountCourseextends 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|Mybatis 一级缓存和二级缓存的使用
- java|linux连接Redis客户端
- 《Effective Java》第54条(返回零长度的数组或者集合,而不是null)
- MySQL|MySQL慢SQL调优
- 网络|ARP防御篇-如何揪出“内鬼”并“优雅的还手”
- 安全|Apache Commons Configuration远程代码执行漏洞(CVE-2022-33980)分析&复现
- Java|MySQL调优之SQL语句(如何写出高性能SQL语句())
- java|2022年最新阿里java面试题(java初级+中级+高级面试题(附答案))
- 大数据|腾讯云云原生数据湖DLC重磅推出免运维、零成本、高性能spark shuffle manager