此笔记从B站狂神说Java 获取什么是设计模式
文章图片
学习设计模式的意义
文章图片
GoF23
文章图片
oop七大原则 (1)开闭原则: 一个软件的实体应当对扩展开放,对修改关闭;
(2)里氏替换原则:继承必须确保超类所拥有的性质在子类中仍然成立
(3)依赖倒置原则:要面向接口编程,不要面向实现编程。
(4)单一职责原则:控制类的粒度大小、将对象解耦、提高其内聚性。
(5)接口隔离原则:要为各个类建立它们需要的专用接口
(6)迪米特法则:只与你的直接朋友交谈,不跟“陌生人”说话。
(7)合成复用原则:尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。
工厂模式 1、作用:实现创建者和调用者分离
2、00P七大原则:
(1)开闭原则: 一个软件的实体应当对扩展开放,对修改关闭;
(2)依赖倒转原则:要针对接口编程,不要针对实现编程;
(3)迪米特法则:只与你直接的朋友通信,而避免和陌生人通信;
3、核心本质:
(1)实例化对象不使用new, 用工厂方法代替
(2)将选择实现类, 创建对象统一管理和控制。 从而将调用者跟我们的实现类解耦。
文章图片
简单工厂模式1.Car接口
package com.etc.factory.simple;
public interface Car {
void name();
}
2.车 WuLing
package com.etc.factory.simple;
public class WuLing implements Car{
@Override
public void name() {
System.out.println("五菱");
}
}
3.车 Tesla
package com.etc.factory.simple;
public class Tesla implements Car{
@Override
public void name() {
System.out.println("特斯拉");
}
}
4.CarFactory (创建工厂)
package com.etc.factory.simple;
//简单工厂模式 静态工厂模式
//开闭原则
public class CarFactory {
//方法一
public static Car getCar(String car) {
//如果添加其他类,需要修改下列代码,修改逻辑
if (car.equals("五菱")) {
return new WuLing();
}else if (car.equals("特斯拉")) {
return new Tesla();
}else {
return null;
}
}//出现问题 增加一个车呢?
//方法二不修改原逻辑的情况下
public static Car getwuling() {
return new WuLing();
}
public static Car getTesla() {
return new Tesla();
}
}
5.Consumer
package com.etc.factory.simple;
public class Consumer {
public static void main(String[] args) {
// 1 常规创建
//Car car1=new WuLing();
//Car car2=new Tesla();
// 2 使用工厂创建
Car car1 = CarFactory.getCar("五菱");
Car car2 = CarFactory.getCar("特斯拉");
car1.name();
car2.name();
}
}
工厂方法模式1.car接口
package com.etc.factory.method;
public interface Car {
void name();
}
2.CarFactory接口
package com.etc.factory.method;
//工厂方法模式
public interface CarFactory {
Car getCar();
}
3.车 WuLing
package com.etc.factory.simple;
public class WuLing implements Car{
@Override
public void name() {
System.out.println("五菱");
}
}
4.给五菱单独创建个工厂 WuLingFactory
package com.etc.factory.method;
public class WuLingFactory implements CarFactory {
@Override
public Car getCar() {
return new WuLing();
}
}
5.车 Tesla
package com.etc.factory.simple;
public class Tesla implements Car{
@Override
public void name() {
System.out.println("特斯拉");
}
}
6.给Tesla单独创建个工厂 TeslaFactory
package com.etc.factory.method;
public class TeslaFactory implements CarFactory{
@Override
public Car getCar() {
return new Tesla();
}
}
7.Consumer
package com.etc.factory.method;
public class Consumer {
public static void main(String[] args) {Car car1 = new WuLingFactory().getCar();
Car car2 = new TeslaFactory().getCar();
car1.name();
car2.name();
}
}
结构复杂度: simple
代码复杂度: simple
编程复杂度: simple
管理上的复杂度: simple
根据设计原则:工厂方法模式!
根据实际业务:简单工厂模式!
图片解释
文章图片
文章图片
抽象工厂模式
文章图片
文章图片
代码演示1.IPhoneProduct接口
//手机产品接口
public interface IPhoneProduct {
void start();
void shutdown();
void callup();
void sendMS();
}
2.IRouteProduct接口
//路由器产品接口
public interface IRouteProduct {
void start();
void shutdown();
void openWife();
void setting();
}
3.小米手机
package com.etc.factory.abstract1;
public class XiaomiPhone implements IPhoneProduct {
@Override
public void start() {
System.out.println("开启小米手机");
}@Override
public void shutdown() {
System.out.println("关闭小米手机");
}@Override
public void callup() {
System.out.println("小米打电话");
}@Override
public void sendMS() {
System.out.println("小米发短信");
}
}
4.小米路由器
package com.etc.factory.abstract1;
public class XiaomiRouter implements IRouteProduct{
@Override
public void start() {
System.out.println("启动小米路由器");
}@Override
public void shutdown() {
System.out.println("关闭小米路由器");
}@Override
public void openWife() {
System.out.println("开启小米wifi");
}@Override
public void setting() {
System.out.println("设置小米路由器");
}
}
5.华为手机
package com.etc.factory.abstract1;
public class HuaweiPhone implements IPhoneProduct {
@Override
public void start() {
System.out.println("开启华为手机");
}@Override
public void shutdown() {
System.out.println("关闭华为手机");
}@Override
public void callup() {
System.out.println("华为打电话");
}@Override
public void sendMS() {
System.out.println("华为发短信");
}
}
6.华为路由器
package com.etc.factory.abstract1;
public class HuaweiRouter implements IRouteProduct{
@Override
public void start() {
System.out.println("启动华为路由器");
}@Override
public void shutdown() {
System.out.println("关闭华为路由器");
}@Override
public void openWife() {
System.out.println("开启华为wifi");
}@Override
public void setting() {
System.out.println("设置华为路由器");
}
}
7.抽象工厂
package com.etc.factory.abstract1;
//抽象产品工厂
public interface IProductFactory {
//生产手机
IPhoneProduct iphoneProduct();
//生产路由器
IRouteProduct routeProduct();
}
8.小米工厂
package com.etc.factory.abstract1;
public class XiaomiFactory implements IProductFactory{
@Override
public IPhoneProduct iphoneProduct() {
return new XiaomiPhone();
}@Override
public IRouteProduct routeProduct() {
return new XiaomiRouter();
}
}
9.华为工厂
package com.etc.factory.abstract1;
public class HuaweiFactory implements IProductFactory{
@Override
public IPhoneProduct iphoneProduct() {
return new HuaweiPhone();
}@Override
public IRouteProduct routeProduct() {
return new HuaweiRouter();
}
}
10.客户端使用
package com.etc.factory.abstract1;
public class Client {
public static void main(String[] args) {
System.out.println("=======小米系列产品=========");
XiaomiFactory xiaomiFactory = new XiaomiFactory();
IPhoneProduct iPhoneProduct = xiaomiFactory.iphoneProduct();
iPhoneProduct.callup();
iPhoneProduct.sendMS();
IRouteProduct iRouteProduct = xiaomiFactory.routeProduct();
iRouteProduct.openWife();
System.out.println("=======华为系列产品=========");
HuaweiFactory huaweiFactory = new HuaweiFactory();
iPhoneProduct = huaweiFactory.iphoneProduct();
iPhoneProduct.callup();
iPhoneProduct.sendMS();
iRouteProduct = huaweiFactory.routeProduct();
iRouteProduct.openWife();
}
}
建造者模式
文章图片
文章图片
代码演示1.抽象的建造者
package com.etc.factory.builder;
//抽象的建造者 : 方法
public abstract class Builder {
abstract void buildA();
//地基
abstract void buildB();
//钢筋工程
abstract void buildC();
//铺电线
abstract void buildD();
//粉刷//完工 :得到产品
abstract Product getProduct();
}
2.产品: 房子
package com.etc.factory.builder;
//产品: 房子
public class Product {
private String buildA;
private String buildB;
private String buildC;
private String buildD;
public String getBuildA() {
return buildA;
}public void setBuildA(String buildA) {
this.buildA = buildA;
}public String getBuildB() {
return buildB;
}public void setBuildB(String buildB) {
this.buildB = buildB;
}public String getBuildC() {
return buildC;
}public void setBuildC(String buildC) {
this.buildC = buildC;
}public String getBuildD() {
return buildD;
}public void setBuildD(String buildD) {
this.buildD = buildD;
}@Override
public String toString() {
return "Product{" +
"buildA='" + buildA + '\'' +
", buildB='" + buildB + '\'' +
", buildC='" + buildC + '\'' +
", buildD='" + buildD + '\'' +
'}';
}
}
3.具体的建造者
package com.etc.factory.builder;
//具体的建造者 : 工人
public class Worker extends Builder {
private Product product;
public Worker(){
product=new Product();
}
@Override
void buildA() {
product.setBuildA("地基");
System.out.println("地基");
}@Override
void buildB() {
product.setBuildB("钢筋工程");
System.out.println("钢筋工程");
}@Override
void buildC() {
product.setBuildB("铺电线");
System.out.println("铺电线");
}@Override
void buildD() {
product.setBuildB("粉刷");
System.out.println("粉刷");
}@Override
Product getProduct() {
return product;
}
}
4.指挥者
package com.etc.factory.builder;
//指挥 :核心 负责指挥构建一个工程,工程如何构建,由它决定
public class Director {//指挥工人按照顺序建房子
public Product build(Builder builder){
builder.buildA();
builder.buildB();
builder.buildC();
builder.buildD();
return builder.getProduct();
}
}
5.测试
package com.etc.factory.builder;
public class Test {
public static void main(String[] args) {
//指挥
Director director = new Director();
//指挥 具体的工人完成产品
Product build = director.build(new Worker());
//顺序由工人决定
System.out.println(build.toString());
}
}
代码再理解1.建造者
package com.etc.factory.builder2;
//建造者
public abstract class Builder {
abstract Builder buildA(String msg);
//汉堡
abstract Builder buildB(String msg);
//可乐
abstract Builder buildC(String msg);
//薯条
abstract Builder buildD(String msg);
//甜点abstract Product getProduct();
}
2.产品
package com.etc.factory.builder2;
//产品 : 套餐
public class Product {
private String BuildA="汉堡";
private String BuildB="可乐";
private String BuildC="薯条";
private String BuildD="甜点";
public String getBuildA() {
return BuildA;
}public void setBuildA(String buildA) {
BuildA = buildA;
}public String getBuildB() {
return BuildB;
}public void setBuildB(String buildB) {
BuildB = buildB;
}public String getBuildC() {
return BuildC;
}public void setBuildC(String buildC) {
BuildC = buildC;
}public String getBuildD() {
return BuildD;
}public void setBuildD(String buildD) {
BuildD = buildD;
}@Override
public String toString() {
return "Product{" +
"BuildA='" + BuildA + '\'' +
", BuildB='" + BuildB + '\'' +
", BuildC='" + BuildC + '\'' +
", BuildD='" + BuildD + '\'' +
'}';
}
}
3.具体的建造者
package com.etc.factory.builder2;
//具体的建造者
public class Worker extends Builder{private Product product;
public Worker(){
product=new Product();
}
@Override
Builder buildA(String msg) {
product.setBuildA(msg);
return this;
}@Override
Builder buildB(String msg) {
product.setBuildB(msg);
return this;
}@Override
Builder buildC(String msg) {
product.setBuildC(msg);
return this;
}@Override
Builder buildD(String msg) {
product.setBuildD(msg);
return this;
}@Override
Product getProduct() {
return product;
}}
4.测试
package com.etc.factory.builder2;
public class Test {
public static void main(String[] args) {
//服务员
Worker worker = new Worker();
//链式编程 : 在原来的基础上,可以自由组合了,如果不组合,也有默认的套餐
Product product = worker.buildA("全家桶")
.buildB("雪碧").getProduct();
System.out.println(product.toString());
//Product{BuildA='全家桶', BuildB='雪碧', BuildC='薯条', BuildD='甜点'}
}
}
原型模式
代码演示 demo011.Video
package com.etc.prototype.demo01;
import java.util.Date;
/**
* 1.实现一个接口 Cloneable
* 2.重写一个方法 clone()
*/
public class Video implements Cloneable{private String name;
private Date createTime;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}public Video() {
}public Video(String name, Date createTime) {
this.name = name;
this.createTime = createTime;
}public String getName() {
return name;
}public void setName(String name) {
this.name = name;
}public Date getCreateTime() {
return createTime;
}public void setCreateTime(Date createTime) {
this.createTime = createTime;
}@Override
public String toString() {
return "Video{" +
"name='" + name + '\'' +
", createTime=" + createTime +
'}';
}
}
2.Bilibili
package com.etc.prototype.demo01;
import java.util.Date;
/**
* 客户端 : 克隆
*/
public class Bilibili {
public static void main(String[] args) throws CloneNotSupportedException {
//原型对象 v1
Date date = new Date();
Video v1 = new Video("狂神说java", date);
Video v2 = (Video) v1.clone();
System.out.println("v1=>"+v1);
System.out.println("v2=>"+v2);
System.out.println("=======");
date.setTime(21312231);
//没有发生改变
System.out.println("v1=>"+v1);
System.out.println("v2=>"+v2);
/*
v1=>Video{name='狂神说java', createTime=Sat Feb 19 14:39:15 CST 2022}
v2=>Video{name='狂神说java', createTime=Sat Feb 19 14:39:15 CST 2022}
=======
v1=>Video{name='狂神说java', createTime=Thu Jan 01 13:55:12 CST 1970}
v2=>Video{name='狂神说java', createTime=Thu Jan 01 13:55:12 CST 1970}
*/
}
}
/*
//v1 克隆 v2
//Video v2 = new Video("狂神说java", date);
Video v2 = (Video) v1.clone();
System.out.println("v2=>"+v2);
System.out.println("v2=>hash:"+v2.hashCode());
* v1=>Video{name='狂神说java', createTime=Sat Feb 19 14:33:53 CST 2022}
v1=>hash:1028214719
v2=>Video{name='狂神说java', createTime=Sat Feb 19 14:33:53 CST 2022}
v2=>hash:500977346v2.setName("Clone:狂神说java");
System.out.println("v2=>"+v2);
//v2=>Video{name='Clone:狂神说java', createTime=Sat Feb 19 14:34:49 CST 2022}*/
文章图片
代码演示 demo02 深克隆1.Video
package com.etc.prototype.demo02;
import java.util.Date;
public class Video implements Cloneable{private String name;
private Date createTime;
@Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone();
//实现深克隆~
Video v = (Video) obj;
v.createTime = (Date) this.createTime.clone();
//将这个对象的属性也进行克隆~
return obj;
}public Video() {
}public Video(String name, Date createTime) {
this.name = name;
this.createTime = createTime;
}public String getName() {
return name;
}public void setName(String name) {
this.name = name;
}public Date getCreateTime() {
return createTime;
}public void setCreateTime(Date createTime) {
this.createTime = createTime;
}@Override
public String toString() {
return "Video{" +
"name='" + name + '\'' +
", createTime=" + createTime +
'}';
}
}
2.Bilibili
package com.etc.prototype.demo02;
import java.util.Date;
//原型模式+工厂模式==》new 《=》 原型模式
public class Bilibili {
public static void main(String[] args) throws CloneNotSupportedException {
//原型对象 v1
Date date = new Date();
Video v1 = new Video("狂神说java", date);
Video v2 = (Video) v1.clone();
System.out.println("v1=>"+v1);
System.out.println("v2=>"+v2);
System.out.println("=======");
date.setTime(21312231);
System.out.println("v1=>"+v1);
System.out.println("v2=>"+v2);
/*
v1=>Video{name='狂神说java', createTime=Sat Feb 19 14:43:22 CST 2022}
v2=>Video{name='狂神说java', createTime=Sat Feb 19 14:43:22 CST 2022}
=======
v1=>Video{name='狂神说java', createTime=Thu Jan 01 13:55:12 CST 1970}
v2=>Video{name='狂神说java', createTime=Sat Feb 19 14:43:22 CST 2022}
*/
}
}
适配器模式
文章图片
文章图片
代码演示1.Adaptee
package com.etc.adapter;
//要被适配的类 : 网线
public class Adaptee {
public void request(){
System.out.println("连接网线上网");
}
}
2.NetToUsb
package com.etc.adapter;
//接口转换器的抽象实现
public interface NetToUsb {
//作用: 处理请求 网线=》usb
public void handleRequest();
}
3.Adapter
package com.etc.adapter;
//真正的适配器 需要连接USB,连接网线//继承 (类适配器 单继承)
//组合 (对象适配器:常用)
public class Adapter extends Adaptee implements NetToUsb{@Override
public void handleRequest() {
super.request();
//可以上网了
}
}
4.Computer
package com.etc.adapter;
//客户端类:想上网插不上网线
public class Computer {
//我们的电脑需要连接上转接器才可以上网
public void net(NetToUsb netToUsb){
//上网的具体实现~ 找一个转接头
netToUsb.handleRequest();
}public static void main(String[] args) {
//电脑 适配器 网线
Computer computer = new Computer();
Adaptee adaptee = new Adaptee();
Adapter adapter = new Adapter();
Adapter2 adapter2=new Adapter2(adaptee);
// computer.net(adapter);
computer.net(adapter2);
}
}
升级版 Adapter2
package com.etc.adapter;
//真正的适配器 需要连接USB,连接网线//继承 (类适配器 单继承)
//组合 (对象适配器:常用)
public class Adapter2implements NetToUsb{
private Adaptee adaptee;
public Adapter2(Adaptee adaptee) {
this.adaptee = adaptee;
}@Override
public void handleRequest() {
adaptee.request();
}
}
桥接模式
文章图片
文章图片
文章图片
代码演示1.Brand
package com.etc.bridge;
//品牌
public interface Brand {
void info();
}
2.Lenovo联想品牌
package com.etc.bridge;
//联想品牌
public class Lenovo implements Brand{
@Override
public void info() {
System.out.print("联想");
}
}
3.苹果品牌
package com.etc.bridge;
//苹果品牌
public class Apple implements Brand{@Override
public void info() {
System.out.print("苹果");
}
}
4.组合
package com.etc.bridge;
//抽象的电脑类型类
public abstract class Computer {
//组合 品牌
protected Brand brand;
public Computer(Brand brand) {
this.brand = brand;
}publicvoid info(){
brand.info();
//自带品牌
}
}
class Desktop extends Computer{public Desktop(Brand brand) {
super(brand);
}@Override
public void info() {
super.info();
System.out.print("台式机");
}
}class Laptop extends Computer{public Laptop(Brand brand) {
super(brand);
}@Override
public void info() {
super.info();
System.out.print("笔记本");
}
}
【设计模式|23种设计模式】5.测试
package com.etc.bridge;
public class Test {
public static void main(String[] args) {
//苹果笔记本
Computer computer = new Laptop(new Apple());
computer.info();
System.out.println();
//联想台式机
Computer computer2 = new Desktop(new Lenovo());
computer2.info();
}
}
推荐阅读
- 面试|我经历的IT公司面试及离职感受(转)
- java|设计模式——创建型——工厂方法(Factory Method)
- 设计模式|设计模式_创建型模式——工厂方法
- 设计模式|设计模式——创建型软件设计模式——工厂方法模式
- 设计模式之装饰器模式
- 设计模式之设计原则
- 设计模式六大原则(5)(迪米特法则 最少知道)
- 观察者模式实现之EventBus(Google)
- Java高级面试|常见设计模式——装饰模式