java|设计模式第一回

一 UML 1.1 UML Class 1.1 子类指向父类
java|设计模式第一回
文章图片

1.2 实现继承、虚线实现
java|设计模式第一回
文章图片

java|设计模式第一回
文章图片

1.3 实现关联,虚线依赖
java|设计模式第一回
文章图片

java|设计模式第一回
文章图片

虚线:
java|设计模式第一回
文章图片

实线:
java|设计模式第一回
文章图片

1.4 空心菱形-聚合 实心菱形-组合
java|设计模式第一回
文章图片

java|设计模式第一回
文章图片

java|设计模式第一回
文章图片

java|设计模式第一回
文章图片

java|设计模式第一回
文章图片

java|设计模式第一回
文章图片

1.5 案例
java|设计模式第一回
文章图片

1.2 UML时序图 java|设计模式第一回
文章图片

java|设计模式第一回
文章图片

二 设计原则 设计原则:

  • 开闭原则
  • 依赖倒置原则
  • 单一职责原则
  • 接口隔离原则
  • 迪米特法则(最少知道原则)
  • 里氏替换原则
  • 合成、复用原则(组合、复用原则)
    2.1 开闭原则 一个软件实体如类,模块或者函数应该对扩展开放,对修改关闭(开闭)。强调的是用抽象构建框架,用实现扩展细节。按照这个原则的优点就是提高软件的可复用性和可维护性。----面向抽象编程。
举例有个课程的设计,面向抽象编程首先课程定义成接口,课程有获取课程id,课程名称,课程价格的三个抽象方法
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; } }

java|设计模式第一回
文章图片

我们编写一个测试类,来获取某个具体课程的名称,价格等:
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()); } }

    推荐阅读