一、UML
1.1 UML的定义
UML:统一建模语言(Unified Modeling Language,UML)是一种为面向对象系统的产品进行说明、可视化和编制文档的一种标准语言,是非专利的第三代建模和规约语言。UML是面向对象设计的建模工具,独立于任何具体程序设计语言。
1.2 UML的作用
(1)为软件系统建立可视化模型。
UML符号具有良好的语义,不会引起歧义;基于UML的可视化模型,使系统结构直观、易于理解;使用UML进行软件系统的模型不但有利于系统开发人员和系统用户的交流,还有利于系统维护。模型是系统的蓝图,它可以对开发人员的规划进行补充,模型可以帮助开发人员规划要建的系统。有了正确的模型就可以实现正确的系统设计,保证用户的要求得到满足,系统能在需求改变时站得住脚。对于一个软件系统,模型就是开发人员为系统设计的一组视图。这组视图不仅描述了用户需要的功能,还描述了怎样去实现这些功能。(2)为软件系统建立构件。
UML不是面向对象的编程语言,但它的模型可以直接对应到各种各样的编程语言。例如,它可以使用代码生成器工具将UML模型转换为多种程序设计语言代码,如可生成C++,XML,DTD,JAVA, Visual basic等语言的代码,或使用反向生成器工具将程序源代码转换为UML;甚至还可以生成关系数据库中的表。(3)为软件系统建立文档。
UML可以为系统的体系结构及其所有细节建立文档。不同的UML模型图可以作为项目不同阶段的软件开发文档。
1.3 UML的分类
UML2.2中一共定义了14种图示,分类如下:
结构式图形:强调的是系统式的建模
行为式图形:强调系统模型中的触发事件
交互式图形:属于行为式图形子集,强调系统模型种的资料流程
1.3.1 静态图
静态图(类图,对象图,包图)
实现图(组件图,部署图)
剖面图
复合结构图
1.3.2 行为式图形
活动图
状态图
用例图
1.3.3 交互式图形
通信图
交互概述图
时序图
时间图
1.4 UML类图
Class Diagram:用于表示类、接口、实例之间相互静态关系
常见的符号含义
1 UML箭头方向:从子类指向父类(只有知道对方信息时才能指向对方)
2 实线:代表继承了父类(关联关系)
3 虚线:代表实现了一个接口(依赖关系)
4 空心菱形:聚合关系
5 实心菱形:组合关系
常见的数字表达及含义
假设A类和B类,数字标记在A类侧
0…1 : 0或1个实例
0…: 0或多个实例
1…1: 1个实例
1 : 只能有一个实例
1…: 至少有一个实例
1.5 UML时序图
Sequence Diagram:是显示对象之间交互的图,这些对象是按时间顺序排列的
时序图中包括的建模元素主要有:对象(Actor)、生命线(Lifeline)、控制焦点(Focus of control)、消息(message)、同步调用、异步调用
1.6 类的表示
一个正常的类
line 1 GeelyClass :一个正常的类
属性
line 2 + 表示public权限 :String 代表类型
line 3 - 表示private权限
line 4 # 表示protected权限
line 5 ~ 表示default权限
line 6 下划线代表静态属性(同理方法代表静态方法)
行为
+study( ) : 斜体代表抽象方法
+openMac( ) : boolean 表示返回值boolean类型
1.7 UML类关系图
类关系图来自大话设计模式
二、设计原则
2.1 七大设计原则
1 开闭原则
2 依赖倒置原则
3 单一职责原则
4 接口隔离原则
5 迪米特法则(最少知道原则)
6 里氏替换原则
7 合成复原原则
在系统的设计过程中也不是完全遵守七大原则,需要做相应的取舍,讲究一个度,一个平衡。
2.2 开闭原则
类图
实例代码
package com.geely.design.principle.openclose;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/7
*/
public interface ICourse {
Integer getId();
String getName();
Double getPrice();
}
package com.geely.design.principle.openclose;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/7
*/
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;
}
}
package com.geely.design.principle.openclose;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe 扩展而不修改
* @Date 2022/4/7
*/
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;
}
}
package com.geely.design.principle.openclose;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/7
*/
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() + "元");
}
}
2.3 依赖倒置原则
类图
代码实现
package com.geely.design.principle.dependenceinversion;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/7
*/
public interface ICourse {
void studyCourse();
}
package com.geely.design.principle.dependenceinversion;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/7
*/
public class FECourse implements ICourse {
@Override
public void studyCourse() {
System.out.println("Geely在学习FE课程");
}
}
package com.geely.design.principle.dependenceinversion;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/7
*/
public class JavaCourse implements ICourse {
@Override
public void studyCourse() {
System.out.println("Geely在学习Java课程");
}
}
package com.geely.design.principle.dependenceinversion;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/7
*/
public class PythonCourse implements ICourse {
@Override
public void studyCourse() {
System.out.println("Geely在学习Python课程");
}
}
package com.geely.design.principle.dependenceinversion;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/7
*/
public class Geely {
public void setiCourse(ICourse iCourse) {
this.iCourse = iCourse;
}
private ICourse iCourse;
public void studyImoocCourse(){
iCourse.studyCourse();
}
}
package com.geely.design.principle.dependenceinversion;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/7
*/
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();
}
}
2.4 单一职责原则
类图
代码实现
package com.geely.design.principle.singleresponsibility;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public class Bird {
public void mainMoveMode(String birdName){
if("鸵鸟".equals(birdName)){
System.out.println(birdName+"用脚走");
}else{
System.out.println(birdName+"用翅膀飞");
}
}
}
package com.geely.design.principle.singleresponsibility;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public class WalkBird {
public void mainMoveMode(String birdName){
System.out.println(birdName+"用脚走");
}
}
package com.geely.design.principle.singleresponsibility;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public class FlyBird {
public void mainMoveMode(String birdName){
System.out.println(birdName+"用翅膀飞");
}
}
package com.geely.design.principle.singleresponsibility;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
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("鸵鸟");
}
}
课程类图
代码
package com.geely.design.principle.singleresponsibility;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public interface ICourseManager {
void studyCourse();
void refundCourse();
}
package com.geely.design.principle.singleresponsibility;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public interface ICourseContent {
String getCourseName();
byte[] getCourseVideo();
}
package com.geely.design.principle.singleresponsibility;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public class CourseImpl implements ICourseManager,ICourseContent {
@Override
public void studyCourse() {
}
@Override
public void refundCourse() {
}
@Override
public String getCourseName() {
return null;
}
@Override
public byte[] getCourseVideo() {
return new byte[0];
}
}
package com.geely.design.principle.singleresponsibility;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public class Method {
private void updateUserInfo(String userName,String address){
userName = "geely";
address = "beijing";
}
private void updateUserInfo(String userName,String... properties){
userName = "geely";
// address = "beijing";
}
private void updateUsername(String userName){
userName = "geely";
}
private void updateUserAddress(String address){
address = "beijing";
}
private void updateUserInfo(String userName,String address,boolean bool){
if(bool){
//todo something1
}else{
//todo something2
}
userName = "geely";
address = "beijing";
}
}
2.5 接口隔离原则
单一职责针对的是类
接口隔离针对的是接口
类图
代码
package com.geely.design.principle.interfacesegregation;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public interface IAnimalAction {
void eat();
void fly();
void swim();
}
package com.geely.design.principle.interfacesegregation;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public class Bird implements IAnimalAction {
@Override
public void eat() {
}
@Override
public void fly() {
}
@Override
public void swim() {
}
}
package com.geely.design.principle.interfacesegregation;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public interface IEatAnimalAction {
void eat();
}
package com.geely.design.principle.interfacesegregation;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public interface IFlyAnimalAction {
void fly();
}
package com.geely.design.principle.interfacesegregation;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public interface ISwimAnimalAction {
void swim();
}
package com.geely.design.principle.interfacesegregation;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public class Dog implements ISwimAnimalAction,IEatAnimalAction {
@Override
public void eat() {
}
@Override
public void swim() {
}
}
2.6 迪米特原则
最少知道原则
类图
代码
package com.geely.design.principle.demeter;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public class Boss {
public void commandCheckNumber(TeamLeader teamLeader){
teamLeader.checkNumberOfCourses();
}
}
package com.geely.design.principle.demeter;
import java.util.ArrayList;
import java.util.List;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
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());
}
}
package com.geely.design.principle.demeter;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public class Course {
}
package com.geely.design.principle.demeter;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public class Test {
public static void main(String[] args) {
Boss boss = new Boss();
TeamLeader teamLeader = new TeamLeader();
boss.commandCheckNumber(teamLeader);
}
}
输出
在线课程的数量是:20
Process finished with exit code 0
2.7 里氏替换原则
类图
代码
package com.geely.design.principle.liskovsubstitution;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public interface Quadrangle {
long getWidth();
long getLength();
}
package com.geely.design.principle.liskovsubstitution;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
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;
}
}
package com.geely.design.principle.liskovsubstitution;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public class Square implements Quadrangle {
private long sideLength;
public long getSideLength() {
return sideLength;
}
public void setSideLength(long sideLength) {
this.sideLength = sideLength;
}
@Override
public long getWidth() {
return sideLength;
}
@Override
public long getLength() {
return sideLength;
}
}
package com.geely.design.principle.liskovsubstitution;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
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 static void main(String[] args) {
Square square = new Square();
// square.setLength(10);
// resize(square);
}
}
2.8 合成复用原则
类图
代码
package com.geely.design.principle.compositionaggregation;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public abstract class DBConnection {
// public String getConnection(){
// return "MySQL数据库连接";
// }
public abstract String getConnection();
}
package com.geely.design.principle.compositionaggregation;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public class MySQLConnection extends DBConnection {
@Override
public String getConnection() {
return "MySQL数据库连接";
}
}
package com.geely.design.principle.compositionaggregation;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public class PostgreSQLConnection extends DBConnection {
@Override
public String getConnection() {
return "PostgreSQL数据库连接";
}
}
package com.geely.design.principle.compositionaggregation;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
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+"增加产品");
}
}
package com.geely.design.principle.compositionaggregation;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public class Test {
public static void main(String[] args) {
ProductDao productDao = new ProductDao();
productDao.setDbConnection(new PostgreSQLConnection());
productDao.addProduct();
}
}
三、简单工厂
3.1 定义
简单工厂定义:由一个工厂对象决定创建出哪一种产品的实例
类型:创建型 但不属于23种之中
使用场景:
1 工厂类负责创建的对象比较少
2 客户端只知道传入工厂类的参数,对于如何创建对象的(逻辑)不关心优点: 只需要传入一个正确的参数,就可以获取到要获取的对象,无须知道创建细节
缺点:新增产品需要修改工厂类的判断逻辑,违背了开闭原则
3.2 类图
3.3 简单工厂代码
package com.geely.design.pattern.creational.simplefactory;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public abstract class Video {
public abstract void produce();
}
package com.geely.design.pattern.creational.simplefactory;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public class JavaVideo extends Video {
@Override
public void produce() {
System.out.println("录制Java课程视频");
}
}
package com.geely.design.pattern.creational.simplefactory;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public class PythonVideo extends Video {
@Override
public void produce() {
System.out.println("录制Python课程视频");
}
}
package com.geely.design.pattern.creational.simplefactory;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public class VideoFactory {
public Video getVideo(Class c){
Video video = null;
try {
video = (Video) Class.forName(c.getName()).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return video;
}
public Video getVideo(String type){
if("java".equalsIgnoreCase(type)){
return new JavaVideo();
}else if("python".equalsIgnoreCase(type)){
return new PythonVideo();
}
return null;
}
}
package com.geely.design.pattern.creational.simplefactory;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/8
*/
public class Test {
public static void main(String[] args) {
// VideoFactory videoFactory = new VideoFactory();
// Video video = videoFactory.getVideo("java");
// if(video == null){
// return;
// }
// video.produce();
VideoFactory videoFactory = new VideoFactory();
Video video = videoFactory.getVideo(JavaVideo.class);
if(video == null){
return;
}
video.produce();
}
}
四、工厂方法
4.1 定义
定义:
创建一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行适用场景:
1 创建对象需要大量重复的代码
2 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
3 一个类通过其子类来指定创建哪个对象优点:
1 用户只需要关心产品对应的工厂,无需关系创建的细节
2 加入新产品符合开闭原则,提高扩展性缺点:
1 类的个数容易过多,增加复杂度
2 增加了系统抽象性和理解难度
4.2 类图
VideoFactory是抽象类
FEV、Python、Java实现抽象类VideoFactory,规定了方法
Video是一个抽象类
FEV、Python、Java实现抽象类Video,规定了方法
4.3 产品的代码
package com.geely.design.pattern.creational.factorymethod;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/9
*/
public abstract class Video {
public abstract void produce();
}
package com.geely.design.pattern.creational.factorymethod;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/9
*/
public class PythonVideo extends Video {
@Override
public void produce() {
System.out.println("录制Python课程视频");
}
}
package com.geely.design.pattern.creational.factorymethod;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/9
*/
public class JavaVideo extends Video {
@Override
public void produce() {
System.out.println("录制Java课程视频");
}
}
package com.geely.design.pattern.creational.factorymethod;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/9
*/
public class FEVideo extends Video{
@Override
public void produce() {
System.out.println("录制FE课程视频");
}
}
4.4 工厂的代码
package com.geely.design.pattern.creational.factorymethod;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/9
*/
public abstract class VideoFactory {
public abstract Video getVideo();
}
package com.geely.design.pattern.creational.factorymethod;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/9
*/
public class FEVideoFactory extends VideoFactory{
@Override
public Video getVideo() {
return new FEVideo();
}
}
package com.geely.design.pattern.creational.factorymethod;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/9
*/
public class JavaVideoFactory extends VideoFactory {
@Override
public Video getVideo() {
return new JavaVideo();
}
}
package com.geely.design.pattern.creational.factorymethod;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/9
*/
public class PythonVideoFactory extends VideoFactory {
@Override
public Video getVideo() {
return new PythonVideo();
}
}
4.5 测试类
package com.geely.design.pattern.creational.factorymethod;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/9
*/
public class Test {
public static void main(String[] args) {
VideoFactory videoFactory = new PythonVideoFactory();
VideoFactory videoFactory2 = new JavaVideoFactory();
VideoFactory videoFactory3 = new FEVideoFactory();
Video video = videoFactory.getVideo();
video.produce();
}
}
五、抽象工厂
5.1 定义
定义:抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,无需指定他们具体的类
适用场景:
1 客户端不依赖产品类实例如何被创建、实现等细节
2 强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量的重复代码
3 提供一个产品类的库,所有产品以同样的接口出现,从而使客户端不依赖于具体实现优点:
1 具体产品再应用层代码隔离,无需关心创建细节
2 将一系列的产品族统一到一起创建缺点:
1 规定了所有可能被创建的产品集合,产品族种扩展新的产品困难,需要修改抽象工厂接口
2 增加了系统抽象性和理解程度
产品族和产品等级结构示意图
工厂方法:针对产品等级结构
抽象工厂:针对产品族
5.2 类图
假设现在慕课网工厂生产对象,课程对象和笔记对象,这时如果用工厂方法就会类爆炸,采用抽象工厂会好一点
5.3 Artical代码
package com.geely.design.pattern.creational.abstractfactory;
public abstract class Article {
public abstract void produce();
}
package com.geely.design.pattern.creational.abstractfactory;
public class JavaArticle extends Article {
@Override
public void produce() {
System.out.println("编写Java课程手记");
}
}
package com.geely.design.pattern.creational.abstractfactory;
public class PythonArticle extends Article {
@Override
public void produce() {
System.out.println("编写Python课程手记");
}
}
5.4 Video代码
package com.geely.design.pattern.creational.abstractfactory;
public abstract class Video {
public abstract void produce();
}
package com.geely.design.pattern.creational.abstractfactory;
public class PythonVideo extends Video {
@Override
public void produce() {
System.out.println("录制Python课程视频");
}
}
package com.geely.design.pattern.creational.abstractfactory;
public class JavaVideo extends Video {
@Override
public void produce() {
System.out.println("录制Java课程视频");
}
}
5.5 Factory代码
package com.geely.design.pattern.creational.abstractfactory;
public interface CourseFactory {
Video getVideo();
Article getArticle();
}
package com.geely.design.pattern.creational.abstractfactory;
public class JavaCourseFactory implements CourseFactory {
@Override
public Video getVideo() {
return new JavaVideo();
}
@Override
public Article getArticle() {
return new JavaArticle();
}
}
package com.geely.design.pattern.creational.abstractfactory;
public class PythonCourseFactory implements CourseFactory {
@Override
public Video getVideo() {
return new PythonVideo();
}
@Override
public Article getArticle() {
return new PythonArticle();
}
}
5.6 Test测试代码
如果再增加算法课程,就不用修改其他也可以扩展
package com.geely.design.pattern.creational.abstractfactory;
public class Test {
public static void main(String[] args) {
CourseFactory courseFactory = new JavaCourseFactory();
Video video = courseFactory.getVideo();
Article article = courseFactory.getArticle();
video.produce();
article.produce();
}
}
六、建造者模式
6.1 定义
定义:
1 将一个复杂对象的构建与他的表示分离,使得同样得构建过程可以创建不用得表示
2 用户只需要指定需要建造得类型就可以得到他们,建造过程及细节不需要知道适用场景:
1 如果一个对象有非常复杂得内部结构(很多属性)
2 想把复杂对象得创建和使用分离优点:
1 封装性好,创建和使用分离
2 扩展性好、建造类之间独立、一定程度上解耦缺点:
1 产生多余得Builder对象
2 产品内部发生变化,建造者都要修改,成本较大
建造者和工厂的不同
1 建造者更注重方法的调用顺序
2 工厂注重于创建产品
3 创建对象的粒度不同,工厂创建的都是一样的,建造者创建复杂产品,由各种部件组成
6.2 类图
业务场景:慕课网要发布课程,课程内容包括(ppt、名字、视频、课件、问答),还需要一个讲师负责完成这些内容,涉及到复杂对象的创建
6.3 Builder代码
package com.geely.design.pattern.creational.builder;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/9
*/
public abstract class CourseBuilder {
public abstract void buildCourseName(String courseName);
public abstract void buildCoursePPT(String coursePPT);
public abstract void buildCourseVideo(String courseVideo);
public abstract void buildCourseArticle(String courseArticle);
public abstract void buildCourseQA(String courseQA);
public abstract Course makeCourse();
}
package com.geely.design.pattern.creational.builder;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/9
*/
public class CourseActualBuilder extends CourseBuilder {
private Course course = new Course();
@Override
public void buildCourseName(String courseName) {
course.setCourseName(courseName);
}
@Override
public void buildCoursePPT(String coursePPT) {
course.setCoursePPT(coursePPT);
}
@Override
public void buildCourseVideo(String courseVideo) {
course.setCourseVideo(courseVideo);
}
@Override
public void buildCourseArticle(String courseArticle) {
course.setCourseArticle(courseArticle);
}
@Override
public void buildCourseQA(String courseQA) {
course.setCourseQA(courseQA);
}
@Override
public Course makeCourse() {
return course;
}
}
6.4 Course代码
package com.geely.design.pattern.creational.builder;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/9
*/
public class Course {
private String courseName;
private String coursePPT;
private String courseVideo;
private String courseArticle;
//question & answer
private String courseQA;
public String getCourseName() {
return courseName;
}
public void setCourseName(String courseName) {
this.courseName = courseName;
}
public String getCoursePPT() {
return coursePPT;
}
public void setCoursePPT(String coursePPT) {
this.coursePPT = coursePPT;
}
public String getCourseVideo() {
return courseVideo;
}
public void setCourseVideo(String courseVideo) {
this.courseVideo = courseVideo;
}
public String getCourseArticle() {
return courseArticle;
}
public void setCourseArticle(String courseArticle) {
this.courseArticle = courseArticle;
}
public String getCourseQA() {
return courseQA;
}
public void setCourseQA(String courseQA) {
this.courseQA = courseQA;
}
@Override
public String toString() {
return "Course{" +
"courseName='" + courseName + '\'' +
", coursePPT='" + coursePPT + '\'' +
", courseVideo='" + courseVideo + '\'' +
", courseArticle='" + courseArticle + '\'' +
", courseQA='" + courseQA + '\'' +
'}';
}
}
6.5 Coach代码
package com.geely.design.pattern.creational.builder;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/9
*/
public class Coach {
private CourseBuilder courseBuilder;
public void setCourseBuilder(CourseBuilder courseBuilder) {
this.courseBuilder = courseBuilder;
}
public Course makeCourse(String courseName,String coursePPT,
String courseVideo,String courseArticle,
String courseQA){
this.courseBuilder.buildCourseName(courseName);
this.courseBuilder.buildCoursePPT(coursePPT);
this.courseBuilder.buildCourseVideo(courseVideo);
this.courseBuilder.buildCourseArticle(courseArticle);
this.courseBuilder.buildCourseQA(courseQA);
return this.courseBuilder.makeCourse();
}
}
6.6 Test
package com.geely.design.pattern.creational.builder;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/9
*/
public class Test {
public static void main(String[] args) {
CourseBuilder courseBuilder = new CourseActualBuilder();
Coach coach = new Coach();
coach.setCourseBuilder(courseBuilder);
Course course = coach.makeCourse("Java设计模式精讲",
"Java设计模式精讲PPT",
"Java设计模式精讲视频",
"Java设计模式精讲手记",
"Java设计模式精讲问答");
System.out.println(course);
}
}
6.7 v2版本
实体类和实体类的Builder写在一起,这种写法最常用
package com.geely.design.pattern.creational.builder.v2;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/9
*/
public class Course {
private String courseName;
private String coursePPT;
private String courseVideo;
private String courseArticle;
//question & answer
private String courseQA;
public Course(CourseBuilder courseBuilder) {
this.courseName = courseBuilder.courseName;
this.coursePPT = courseBuilder.coursePPT;
this.courseVideo = courseBuilder.courseVideo;
this.courseArticle = courseBuilder.courseArticle;
this.courseQA = courseBuilder.courseQA;
}
@Override
public String toString() {
return "Course{" +
"courseName='" + courseName + '\'' +
", coursePPT='" + coursePPT + '\'' +
", courseVideo='" + courseVideo + '\'' +
", courseArticle='" + courseArticle + '\'' +
", courseQA='" + courseQA + '\'' +
'}';
}
public static class CourseBuilder{
private String courseName;
private String coursePPT;
private String courseVideo;
private String courseArticle;
//question & answer
private String courseQA;
public CourseBuilder buildCourseName(String courseName){
this.courseName = courseName;
return this;
}
public CourseBuilder buildCoursePPT(String coursePPT) {
this.coursePPT = coursePPT;
return this;
}
public CourseBuilder buildCourseVideo(String courseVideo) {
this.courseVideo = courseVideo;
return this;
}
public CourseBuilder buildCourseArticle(String courseArticle) {
this.courseArticle = courseArticle;
return this;
}
public CourseBuilder buildCourseQA(String courseQA) {
this.courseQA = courseQA;
return this;
}
public Course build(){
return new Course(this);
}
}
}
package com.geely.design.pattern.creational.builder.v2;
import com.google.common.collect.ImmutableSet;
import java.util.Set;
/**
* @Author CandyDingDing
* @Version 1.0
* @Motto 且视他人之疑目如盏盏鬼火,大胆地去走吾之夜路
* @Describe
* @Date 2022/4/9
*/
public class Test {
public static void main(String[] args) {
Course course = new Course.CourseBuilder().buildCourseName("Java设计模式精讲").buildCoursePPT("Java设计模式精讲PPT").buildCourseVideo("Java设计模式精讲视频").build();
System.out.println(course);
Set<String> set = ImmutableSet.<String>builder().add("a").add("b").build();
System.out.println(set);
}
}
参考
慕课网视频地址:https://coding.imooc.com/class/270.html
文档地址:https://www.yuque.com/lililil-9bxsv/kb/bnuf7w
代码地址:https://gitee.com/candydingding/design-pattern.git
视频网盘链接:https://pan.baidu.com/s/1AVqkDa1uAF6mNKH4tD5Vyg 提取码:12ol