设计模式学习笔记
设计模式就是总结前人经验的一套模式
创建型模式:帮我们省去new的过程,帮我们更好的创建对象
工厂模式
核心本质是实例化对象不使用new,用工厂方法代替
工厂模式分为简单工厂模、工厂方法模式、抽象工厂模式
简单工厂模式
简单工厂模式是把new的过程包装了起来,实现对其他类的代理,就像一个工厂一样生产出所需要的类。
好处:不必要关注怎么拿到的车子,只需要告诉工厂我需要什么车子就能生产
坏处:不利于扩展,不满足开闭原则
代码:
车接口
package com.duoyi.demo.designModo.factory.simple;
public interface Car {
void name() ;
}
车1
package com.duoyi.demo.designModo.factory.simple;
public class Tesla implements Car{
@Override
public void name() {
System.out.println("特斯拉!");
}
}
车2
package com.duoyi.demo.designModo.factory.simple;
public class Wulin implements Car{
@Override
public void name() {
System.out.println("五菱宏光");
}
}
车工厂
package com.duoyi.demo.designModo.factory.simple;
//不满足开闭原则,不易扩展
public class CarFactory {
public Car getCar(String carName) {
if (carName.equals("特斯拉")) {
return new Tesla();
} else if (carName.equals("五菱")) {
return new Wulin();
}
return null;
}
}
消费者
package com.duoyi.demo.designModo.factory.simple;
public class Consumer {
public static void main(String[] args) {
Car car1 = new CarFactory().getCar("特斯拉");
Car car2 = new CarFactory().getCar("五菱");
car1.name();
car2.name();
}
}
结果
特斯拉!
五菱宏光
进程已结束,退出代码为 0
工厂方法模式
用接口实现关系,每个车都带一个单独的车工厂,单独车工厂来new相应的车,运用多态的写法就能够实现相关的设计
代码
车接口
package com.duoyi.demo.designModo.factory.simple;
public interface Car {
void name() ;
}
工厂接口
package com.duoyi.demo.designModo.factory.method;
public interface CarFactory {
Car getCar();
}
车1
package com.duoyi.demo.designModo.factory.simple;
public class Tesla implements Car{
@Override
public void name() {
System.out.println("特斯拉!");
}
}
车2工厂
package com.duoyi.demo.designModo.factory.method;
public class TeslaFactory implements CarFactory{
@Override
public Car getCar() {
return new Tesla();
}
}
车2
package com.duoyi.demo.designModo.factory.simple;
public class Wulin implements Car{
@Override
public void name() {
System.out.println("五菱宏光");
}
}
车2接口
package com.duoyi.demo.designModo.factory.method;
public class WulinFactory implements CarFactory{
@Override
public Car getCar() {
return new Wulin();
}
}
消费者
package com.duoyi.demo.designModo.factory.method;
public class Consumer {
public static void main(String[] args) {
Car car1 = new WulinFactory().getCar();
Car car2 = new TeslaFactory().getCar();
car1.name();
car2.name();
}
}
结果
五菱宏光
特斯拉!
进程已结束,退出代码为 0
总结:
简单工厂模式和工厂方法模式对比,在结构复杂度、代码复杂度、编程复杂度、管理上的复杂度上,简单工厂要更好。
根据设计原则,工厂方法模式更符合要求
但是根据实际需要,简单工厂模式用的更多
抽象工厂模式
可以创建其他工厂,更抽象,又称为超级工厂,其他工厂的工厂
代码
手机(产品)
package com.duoyi.demo.designModo.factory.abstractModel;
public interface IphoneProduct {
void start();
void shutdown();
void callUp();
void senSMS();
}
路由器(产品)
package com.duoyi.demo.designModo.factory.abstractModel;
public interface IRouterProduct {
void start();
void shutdown();
void openWifi();
void setting();
}
产品工厂
package com.duoyi.demo.designModo.factory.abstractModel;
public interface IProductFactory {
IphoneProduct productPhone();
IRouterProduct productRouter();
}
华为手机(手机品牌商)
package com.duoyi.demo.designModo.factory.abstractModel;
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 senSMS() {
System.out.println("华为");
}
}
华为路由(路由品牌商)
package com.duoyi.demo.designModo.factory.abstractModel;
public class HuaweiRouter implements IRouterProduct {
@Override
public void start() {
System.out.println("华为路由");
}
@Override
public void shutdown() {
System.out.println("华为路由");
}
@Override
public void openWifi() {
System.out.println("华为路由开wifi");
}
@Override
public void setting() {
System.out.println("华为路由");
}
}
华为工厂(抽象工厂下的具体工厂)
package com.duoyi.demo.designModo.factory.abstractModel;
public class HuaweiProductFactory implements IProductFactory{
@Override
public IphoneProduct productPhone() {
return new HuaweiPhone();
}
@Override
public IRouterProduct productRouter() {
return new HuaweiRouter();
}
}
小米手机(手机品牌商)
package com.duoyi.demo.designModo.factory.abstractModel;
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 senSMS() {
System.out.println("小米");
}
}
小米路由(路由品牌商)
package com.duoyi.demo.designModo.factory.abstractModel;
public class XiaomiRouter implements IRouterProduct {
@Override
public void start() {
System.out.println("小米路由");
}
@Override
public void shutdown() {
System.out.println("小米路由");
}
@Override
public void openWifi() {
System.out.println("小米路由开wifi");
}
@Override
public void setting() {
System.out.println("小米路由");
}
}
小米工厂(抽象工厂下的具体工厂)
package com.duoyi.demo.designModo.factory.abstractModel;
public class XiaomiProductFactory implements IProductFactory{
@Override
public IphoneProduct productPhone() {
return new XiaomiPhone();
}
@Override
public IRouterProduct productRouter() {
return new XiaomiRouter();
}
}
测试
package com.duoyi.demo.designModo.factory.abstractModel;
public class Client {
public static void main(String[] args) {
//同一个抽象工厂生产出不同产品
IphoneProduct xiaomiPhone = new XiaomiProductFactory().productPhone();
IphoneProduct huaweiPhone = new HuaweiProductFactory().productPhone();
xiaomiPhone.callUp();
huaweiPhone.callUp();
IRouterProduct xiaomiRouter = new XiaomiProductFactory().productRouter();
IRouterProduct huaweiRouter = new HuaweiProductFactory().productRouter();
xiaomiRouter.openWifi();
huaweiRouter.openWifi();
}
}
结果
小米手机打电话
华为手机打电话
小米路由开wifi
华为路由开wifi
进程已结束,退出代码为 0
工厂模式总结:
简单工厂模式(静态工厂模式):虽然魔种程度上不符合设计原则,但使用的最多。
工厂方法模式:不修改已有类的前提下,通过增加新的工厂类实现扩展
抽象工厂模式:不可以增加产品,可以增加产品族。适用于稳定不改变的场景
应用场景:
JDK中的Calendar的getInstance方法
JDBC中的Connection对象的获取
Spring中IOC容器创建管理bean对象
反射中Class对象的newInstance方法
建造者模式
建造者模式也是属于创建型模式,帮我们创建对象,适用于复杂业务。
能够把构建和表示分离
代码
建造者(抽象的)
package com.duoyi.demo.designModo.builder;
//抽象的建造者:方法
public abstract class Builder {
abstract void buildA();
abstract void buildB();
abstract void buildC();
abstract void buildD();
//完工:得到产品
abstract Product getProduct();
}
房子(真实需要做的)
package com.duoyi.demo.designModo.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 + '\'' +
'}';
}
}
工人(执行者)
package com.duoyi.demo.designModo.builder;
public class Work extends Builder {
private Product product;
public Work() {
product = new Product();
}
@Override
void buildA() {
product.setBuildA("地基");
System.out.println("地基");
}
@Override
void buildB() {
product.setBuildB("钢筋");
System.out.println("钢筋");
}
@Override
void buildC() {
product.setBuildC("铺电线");
System.out.println("铺电线");
}
@Override
void buildD() {
product.setBuildD("粉刷");
System.out.println("粉刷");
}
@Override
Product getProduct() {
return product;
}
}
指挥(决定执行顺序和执行方法)
package com.duoyi.demo.designModo.builder;
//指挥:核心,负责指挥构建一个工程
public class Director {
public Product build(Builder builder) {
builder.buildA();
builder.buildB();
builder.buildC();
builder.buildD();
return builder.getProduct();
}
}
测试(用户直接使用而不用管怎么来的)
package com.duoyi.demo.designModo.builder;
public class Test {
public static void main(String[] args) {
Director director = new Director();
Product product = director.build(new Work());
System.out.println(product);
}
}
结果
地基
钢筋
铺电线
粉刷
Product{buildA='地基', buildB='钢筋', buildC='铺电线', buildD='粉刷'}
进程已结束,退出代码为 0