常用的设计模式
23种设计模式
创造型模式:单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式
结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式
行为型模式:模板方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、责任链模式、访问者模式
OOP七大原则
一.单例模式
package com.example.demo.single; /** * @Description: 饿汉式单例 * @author: ZYQ * @date: 2021/3/25 10:53 */ public class Hungry { /** * 浪费空间 */ /*private byte[] data1 = new byte[1024 * 1024]; private byte[] data2 = new byte[1024 * 1024]; private byte[] data3 = new byte[1024 * 1024]; private byte[] data4 = new byte[1024 * 1024];*/ //保证构造器私有 private Hungry() { } private final static Hungry HUNGRY = new Hungry(); public static Hungry getInstance() { return HUNGRY; } }
注意点:
构造器私有
饿汉式立即加载对象,可能会造成空间的浪费,一般不使用。
package com.example.demo.single; /** * @Description: 懒汉式单例 * @author: ZYQ * @date: 2021/3/25 11:05 */ public class LazyMan { //构造器私有 private LazyMan() { System.out.println("构造1次"); } private static volatile LazyMan lazyMan = null; public static LazyMan getInstance() { if (lazyMan == null) { synchronized (LazyMan.class) { if (lazyMan == null) { lazyMan = new LazyMan(); } } } return lazyMan; } public static void main(String[] args) { for (int i = 0; i < 100; i++) { new Thread(() -> { LazyMan.getInstance(); }).start(); } } }
懒汉式注意点
1.构造器私有
2.需要使用双重检测。若为单次检测,则多条线程可能同时进入if中,造成多次构造。
3.需要对 lazyMan 对象添加 volatile 修饰词。因此new对象的过程不是原子性的,其分为3步:1.为对象分配内存空间 2.初始化对象 3.将实例指向该空间。在此过程中可能会发生指令重排导致第三步优先于第二步执行。当第三步执行完而还未进行初始化时,若此时有其余线程来到第一层判断,则会误判为lazyMan对象非空,从而直接返回一个空的lazyMan,造成错误。
二.工厂模式
作用:实现了创建者和调用者的分离
详细分类:1.简单工厂模式 2.工厂方法模式 3.抽象工厂模式
核心本质:1.实例化对象不使用new,用工厂方法替代。2.将选择实现类,创建对象统一管理和控制。从而将调用者跟我们的实现类解耦。
一.简单工厂模式
package com.example.demo.factory.simple; /** * @Description: * @author: ZYQ * @date: 2021/3/25 13:39 */ public interface Car { void SayName(); }
package com.example.demo.factory.simple; /** * @Description: * @author: ZYQ * @date: 2021/3/25 13:40 */ public class WuLing implements Car { @Override public void SayName() { System.out.println("我是五菱宏光"); } }
package com.example.demo.factory.simple; /** * @Description: * @author: ZYQ * @date: 2021/3/25 13:45 */ public class Tesla implements Car { @Override public void SayName() { System.out.println("特斯拉"); } }
package com.example.demo.factory.simple; /** * @Description: * @author: ZYQ * @date: 2021/3/25 13:57 */ public class CarFactory { public static Car getCar(String carName) { if (carName.equals("五菱")) return new WuLing(); else if (carName.equals("特斯拉")) return new Tesla(); else return null; } }
package com.example.demo.factory.simple; /** * @Description: * @author: ZYQ * @date: 2021/3/25 14:06 */ public class Consumer { public static void main(String[] args) { Car car = CarFactory.getCar("五菱"); Car car2 = CarFactory.getCar("特斯拉"); car.SayName(); car2.SayName(); } }
简单工厂模式实现起来方便快捷,也不复杂,但是不符合开闭原则。在扩展一个新的实现类时,需要在工厂类中进行相应的代码修改和增加。
二.工厂方法模式
在简单工厂模式的基础上增加下列代码
package com.example.demo.factory.method; /** * @Description: * @author: ZYQ * @date: 2021/3/25 14:17 */ public interface CarFactory { Car getCar(); }
package com.example.demo.factory.method; /** * @Description: * @author: ZYQ * @date: 2021/3/25 14:18 */ public class WuLingFactory implements CarFactory { @Override public Car getCar() { return new WuLing(); } }
package com.example.demo.factory.method; /** * @Description: * @author: ZYQ * @date: 2021/3/25 14:21 */ public class TeslaFactory implements CarFactory { @Override public Car getCar() { return new Tesla(); } }
package com.example.demo.factory.method; /** * @Description: * @author: ZYQ * @date: 2021/3/25 14:06 */ public class Consumer { public static void main(String[] args) { Car wuLing = new WuLingFactory().getCar(); Car tesla = new TeslaFactory().getCar(); wuLing.SayName(); tesla.SayName(); //添加新车 Car MoBai = new MoBaiFactory().getCar(); MoBai.SayName(); } }
细分为了多个工厂,每个工厂对应一种资源
工厂方法模式解决了简单工厂模式的扩展问题,符合开闭原则。但是可以发现其类和接口的数量会非常的多。
三.抽象工厂模式
package com.example.demo.factory.abstractFactory; /** * @Description: 抽象产品工厂 * @author: ZYQ * @date: 2021/3/25 15:54 */ public interface ProductFactory { //生产手机 PhoneProduct productPhone(); //生产路由器 RouterProduct productRouter(); }
package com.example.demo.factory.abstractFactory; /** * @Description: 手机产品接口 * @author: ZYQ * @date: 2021/3/25 15:46 */ public interface PhoneProduct { void start(); void shutdown(); void callUp(); void sendSMS(); }
package com.example.demo.factory.abstractFactory; /** * @Description: 路由器产品接口 * @author: ZYQ * @date: 2021/3/25 15:47 */ public interface RouterProduct { void start(); void shutdown(); void openWifi(); void setting(); }
package com.example.demo.factory.abstractFactory; /** * @Description: * @author: ZYQ * @date: 2021/3/25 16:06 */ public class HuaWeiFactory implements ProductFactory { @Override public PhoneProduct productPhone() { return new HuWeiPhone(); } @Override public RouterProduct productRouter() { return new HuaWeiRouter(); } }
package com.example.demo.factory.abstractFactory; /** * @Description: * @author: ZYQ * @date: 2021/3/25 15:50 */ public class HuaWeiRouter implements RouterProduct { @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.example.demo.factory.abstractFactory; /** * @Description: * @author: ZYQ * @date: 2021/3/25 15:49 */ public class HuWeiPhone implements PhoneProduct{ @Override public void start() { System.out.println("华为手机开启"); } @Override public void shutdown() { System.out.println("关闭华为手机"); } @Override public void callUp() { System.out.println("华为手机打电话"); } @Override public void sendSMS() { System.out.println("华为手机发短信"); } }
package com.example.demo.factory.abstractFactory; /** * @Description: * @author: ZYQ * @date: 2021/3/25 16:08 */ public class Client { public static void main(String[] args) { System.out.println("================小米系列产品===================="); //小米工厂 XiaoMiFactory xiaoMiFactory = new XiaoMiFactory(); PhoneProduct xiaoMiPhone = xiaoMiFactory.productPhone(); xiaoMiPhone.callUp(); RouterProduct xiaoMiRouter = xiaoMiFactory.productRouter(); xiaoMiRouter.openWifi(); System.out.println("================华为系列产品===================="); HuaWeiFactory huaWeiFactory = new HuaWeiFactory(); PhoneProduct huaWeiPhone = huaWeiFactory.productPhone(); huaWeiPhone.callUp(); } }
交叉型的对象统一管理比较适合