设计模式
1、简述
2、基本要素
3、23种设计模式
创建型模式:让创建和使用分离
结构型模式:让类和对象组成更大的结构
行为型模式:让类和对象相互协作完成单个对象无法完成的任务
4、OOP七大原则
开闭原则
里氏替代原则:子类可以扩展方法但父类方法尽量不要改动
依赖倒置原则:面向接口编程
单一职责原则:粒度,一个方法尽可能处理一件事情,说的是具体实现
接口隔离原则:和单一职责原则差不多,说的是接口
迪米特法则:和朋友直接交谈、不跟陌生人交谈
合成复用原则:尽量使用has-a,避免使用is-a
5、工厂设计模式
作用:
分类:
简单工厂模式:也叫静态工厂模式,以工厂类代替new。缺点:违背开闭原则
工厂方法模式:
抽象工厂模式:
传统方式
package model.factory.tradition;
public interface Car {
void name();
}
package model.factory.tradition;
public class WuLing implements Car {
@Override
public void name() {
System.out.println("五菱宏光");
}
}
package model.factory.tradition;
public class Tesla implements Car {
@Override
public void name() {
System.out.println("Tesla");
}
}
package model.factory.tradition;
//传统情况
public class Consumer {
public static void main(String[] args) {
Car car1 = new WuLing();//五菱宏光
Car car2 = new Tesla();//Tesla
car1.name();
car2.name();
}
}
缺点
简单工厂模式
package model.factory.simple;
public interface Car {
void name();
}
package model.factory.simple;
public class WuLing implements Car {
@Override
public void name() {
System.out.println("五菱宏光");
}
}
package model.factory.simple;
public class Tesla implements Car {
@Override
public void name() {
System.out.println("Tesla");
}
}
package model.factory.simple;
public class CarFactory {
public static Car getCar(String car){
if ("五菱宏光".equals(car)){
return new WuLing();
}else if ("Tesla".equals(car)){
return new Tesla();
}else {
return null;
}
}
}
package model.factory.simple;
public class Consumer {
public static void main(String[] args) {
Car car1 = CarFactory.getCar("五菱宏光");
Car car2 = CarFactory.getCar("Tesla");
car1.name();//五菱宏光
car2.name();//Tesla
}
}
优点
缺点
工厂方法模式
package model.factory.method;
public interface Car {
void name();
}
package model.factory.method;
public class WuLing implements Car {
@Override
public void name() {
System.out.println("五菱宏光");
}
}
package model.factory.method;
public class Tesla implements Car {
@Override
public void name() {
System.out.println("Tesla");
}
}
package model.factory.method;
public interface CarFactory {
public Car getCar();
}
package model.factory.method;
public class WuLingFactory implements CarFactory {
@Override
public Car getCar() {
return new WuLing();
}
}
package model.factory.method;
public class TeslaFactory implements CarFactory {
@Override
public Car getCar() {
return new Tesla();
}
}
package model.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();//Tesla
}
}
优点
缺点
写的类有点多
抽象工厂模式
package model.factory.abstract0;
public interface PhoneProduct {
public void callUp();
public void sendMsg();
}
package model.factory.abstract0;
public class XiaomiProduct implements PhoneProduct {
@Override
public void callUp() {
System.out.println("小米手机打电话");
}
@Override
public void sendMsg() {
System.out.println("小米手机发消息");
}
}
package model.factory.abstract0;
public class HuaweiProduct implements PhoneProduct {
@Override
public void callUp() {
System.out.println("华为手机打电话");
}
@Override
public void sendMsg() {
System.out.println("华为手机发消息");
}
}
package model.factory.abstract0;
public interface PhoneRounter {
void openWifi();
void closeWifi();
}
package model.factory.abstract0;
public class XiaomiRounter implements PhoneRounter {
@Override
public void openWifi() {
System.out.println("打开小米路由器");
}
@Override
public void closeWifi() {
System.out.println("关闭小米路由器");
}
}
package model.factory.abstract0;
public class HuaweiRounter implements PhoneRounter {
@Override
public void openWifi() {
System.out.println("打开华为路由器");
}
@Override
public void closeWifi() {
System.out.println("关闭华为路由器");
}
}
package model.factory.abstract0;
public interface PhoneFactory {
PhoneProduct phoneProduct();
PhoneRounter phoneRouter();
}
package model.factory.abstract0;
public class XiaomiFactory implements PhoneFactory {
@Override
public PhoneProduct phoneProduct() {
return new XiaomiProduct();
}
@Override
public PhoneRounter phoneRouter() {
return new XiaomiRounter();
}
}
package model.factory.abstract0;
public class HuaweiFactory implements PhoneFactory {
@Override
public PhoneProduct phoneProduct() {
return new HuaweiProduct();
}
@Override
public PhoneRounter phoneRouter() {
return new HuaweiRounter();
}
}
package model.factory.abstract0;
public class Consumer {
public static void main(String[] args) {
PhoneProduct xiaomiPhone = new XiaomiFactory().phoneProduct();
xiaomiPhone.callUp();//小米手机打电话
xiaomiPhone.sendMsg();//小米手机发消息
PhoneRounter huaweiRouter = new HuaweiFactory().phoneRouter();
huaweiRouter.openWifi();//打开华为路由器
huaweiRouter.closeWifi();//关闭华为路由器
}
}
优点
具体产品在应用层的代码隔离,无需关心创建的细节;
将一个系列的产品统一到一起创建
缺点
扩展性差;
增加了系统的抽象性和理解难度
6、建造者模式
package model.factory.builder;
//抽象建造者
//建造一个产品需要经历几个步骤
public abstract class Builder {
abstract void builderA();//地基
abstract void builderB();//钢筋工程
abstract void builderC();//铺电缆
abstract void builderD();//粉刷
//完工:得到产品
abstract Product getProduct();
}
package model.factory.builder;
public class Product {
private String BuildA;
private String BuildB;
private String BuildC;
private String BuildD;
@Override
public String toString() {
return "Produt{" +
"BuildA='" + BuildA + '\'' +
", BuildB='" + BuildB + '\'' +
", BuildC='" + BuildC + '\'' +
", BuildD='" + 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;
}
}
package model.factory.builder;
//工人就完成这些步骤和返回结果
public class Worker extends Builder {
private Product product;
public Worker() {
product = new Product();
}
@Override
void builderA() {
product.setBuildA("地基");
System.out.println("地基");
}
@Override
void builderB() {
product.setBuildB("钢筋工程");
System.out.println("钢筋工程");
}
@Override
void builderC() {
product.setBuildC("铺电缆");
System.out.println("铺电缆");
}
@Override
void builderD() {
product.setBuildD("粉刷");
System.out.println("粉刷");
}
@Override
Product getProduct() {
return product;
}
}
package model.factory.builder;
//指挥是核心,负责指挥构建一个工程,工程如何构建,由它决定
public class Director {
public Product build(Builder builder){
//指挥工人按顺序建房子
builder.builderA();
builder.builderC();
builder.builderD();
builder.builderB();
return builder.getProduct();
}
}
package model.factory.builder;
public class Test {
public static void main(String[] args) {
//指挥
Director director = new Director();
//指挥具体的工人完成产品
//输出:Produt{BuildA='地基', BuildB='钢筋工程', BuildC='铺电缆', BuildD='粉刷'}
Product build = director.build(new Worker());
System.out.println(build);
}
}
优点
缺点
客户就是Director,没有使用静态内部类的方式,显得僵硬了点
7、原型模式
浅拷贝
package model.factory.prototype.demo1;
import java.util.Date;
public class Video implements Cloneable {
private String name;
private Date createTime;
@Override
public String toString() {
return "Video{" +
"name='" + name + '\'' +
", createTime=" + createTime +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
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;
}
public Video(String name, Date createTime) {
this.name = name;
this.createTime = createTime;
}
public Video() {
}
}
package model.factory.prototype.demo1;
import java.util.Date;
public class Test01 {
public static void main(String[] args) throws CloneNotSupportedException {
Date date = new Date();
Video v1 = new Video("up主", date);
Video v2 = (Video) v1.clone();
System.out.println(v1);
System.out.println(v1.hashCode());
System.out.println("========================");
System.out.println(v2);
System.out.println(v2.hashCode());
}
}
深拷贝
package model.factory.prototype.demo2;
import java.util.Date;
public class Video implements Cloneable {
private String name;
private Date createTime;
@Override
public String toString() {
return "Video{" +
"name='" + name + '\'' +
", createTime=" + createTime +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone();
Video v = (Video) obj;
v.createTime = (Date) this.createTime.clone();
return obj;
}
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;
}
public Video(String name, Date createTime) {
this.name = name;
this.createTime = createTime;
}
public Video() {
}
}
package model.factory.prototype.demo2;
import java.util.Date;
public class Test02 {
public static void main(String[] args) throws CloneNotSupportedException {
Date date = new Date();
Video v1 = new Video("up主", date);
Video v2 = (Video) v1.clone();
System.out.println(v1);
System.out.println(v2);
System.out.println("========================");
date.setTime(21123281);
System.out.println(v1);
System.out.println(v2);
}
}
8、适配器模式
继承方式
package model.adapter;
//网线,用来上网
public class Adaptee {
public void request(){
System.out.println("网线可以用来上网");
}
}
package model.adapter;
//适配器接口,可以造很多种适配器
public interface NetToUsb {
public void handleRequest();
}
package model.adapter;
public class Adapt extends Adaptee implements NetToUsb {
@Override
public void handleRequest() {
super.request();
}
}
package model.adapter;
public class Computer {
public void net(NetToUsb adapt){
//上网的具体实现
adapt.handleRequest();
}
public static void main(String[] args) {
Computer computer = new Computer();
Adapt adapt = new Adapt();
Adaptee adaptee = new Adaptee();
computer.net(adapt);
}
}
组合方式
package model.adapter;
//网线,用来上网
public class Adaptee {
public void request(){
System.out.println("网线可以用来上网");
}
}
package model.adapter;
//适配器接口,可以造很多种适配器
public interface NetToUsb {
public void handleRequest();
}
package model.adapter;
//继承和组合。继承是单继承,也称类适配器;常用的是组合,如下:
public class Adapt2 implements NetToUsb{
private Adaptee adaptee;
public Adapt2(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void handleRequest() {
adaptee.request();
}
}
package model.adapter;
public class Computer {
public void net(NetToUsb adapt){
//上网的具体实现
adapt.handleRequest();
}
public static void main(String[] args) {
Computer computer = new Computer();
Adaptee adaptee = new Adaptee();
Adapt2 adapt2 = new Adapt2(adaptee);
computer.net(adapt2);
}
}
9、桥接模式
package model.bridge;
//品牌用接口
public interface Brand {
void info();
}
package model.bridge;
//联想品牌
public class Lenovo implements Brand {
@Override
public void info() {
System.out.print("联想");
}
}
package model.bridge;
//苹果品牌
public class Apple implements Brand {
@Override
public void info() {
System.out.print("苹果");
}
}
package model.bridge;
//抽象的电脑类型
public abstract class Computer {
//组合、品牌
protected Brand brand;
public Computer(Brand brand) {
this.brand = brand;
}
public void 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("笔记本");
}
}
package model.bridge;
public class Test {
public static void main(String[] args) {
//苹果笔记本
Computer computer1 = new Laptop(new Apple());
computer1.info();
System.out.println();
//联想台式机
Computer computer2 = new Desktop(new Lenovo());
computer2.info();
}
}
特点
避免使用继承而多使用组合。