美文网首页
设计模式

设计模式

作者: 西海岸虎皮猫大人 | 来源:发表于2020-10-20 16:52 被阅读0次

    0 概述

    创建型模式:
    单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式。
    结构型模式:
    适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
    行为型模式:
    模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式

    1 单例模式

    五种实现方式

    1.饿汉式
    /**
     * 单例模式-饿汉式
     * 类初始化时,立即加载这个对象,线程安全
     */
    public class EagerSingleton {
        private static EagerSingleton instance = new EagerSingleton();
    
        /**
         * 私有化构造器
         */
        private EagerSingleton() {}
    
        public static EagerSingleton getInstance() {
            return instance;
        }
    }
    
    2.懒汉式
    /**
     * 单例模式-懒汉式
     * 使用时再创建实例,为保证线程安全需要方法同步,效率低
     */
    public class LazySingleton {
        private static LazySingleton instance;
    
        private LazySingleton() {}
    
        public static synchronized LazySingleton getInstance() {
            if(instance == null) {
                instance =  new LazySingleton();
            }
            return instance;
        }
    }
    
    3.双重检查锁
    /**
     * 单例模式-双重检查锁
     * 由于编译器优化原因和JVM底层内部模型原因,偶尔会出问题,不建议使用
     */
    public class DoubleCheckSingleton {
        private static DoubleCheckSingleton instance;
    
        public static DoubleCheckSingleton getInstance() {
            if(instance == null) {
                DoubleCheckSingleton dc;
                synchronized (DoubleCheckSingleton.class) {
                    dc = instance;
                    if(dc == null) {
                        synchronized (DoubleCheckSingleton.class) {
                            if(dc == null) {
                                dc = new DoubleCheckSingleton();
                            }
                        }
                        instance = dc;
                    }
                }
            }
            return instance;
        }
    }
    
    4.静态内部类
    /**
     * 单例模式-静态内部类
     * 线程安全\延时加载且调用效率高
     */
    public class StaticInnerSingleton {
        private static class StaticInnerSingletonInstance {
            private static final StaticInnerSingleton instance = new StaticInnerSingleton();
        }
    
        private StaticInnerSingleton() {}
    
        public static StaticInnerSingleton getInstance() {
            return StaticInnerSingletonInstance.instance;
        }
    }
    
    5.枚举
    /**
     * 单例模式-枚举
     */
    public enum EnumSingleton {
        INSTANCE;
    }
    

    单例模式测试

    1.测试
    /**
     * 测试五种方式实现单例
     */
    public class Client1 {
        public static void main(String[] args) {
            EagerSingleton e1 = EagerSingleton.getInstance();
            EagerSingleton e2 = EagerSingleton.getInstance();
            System.out.println(e1 == e2);
    
            LazySingleton l1 = LazySingleton.getInstance();
            LazySingleton l2 = LazySingleton.getInstance();
            System.out.println(l1 == l2);
    
            DoubleCheckSingleton d1 = DoubleCheckSingleton.getInstance();
            DoubleCheckSingleton d2 = DoubleCheckSingleton.getInstance();
            System.out.println(d1 == d2);
    
            StaticInnerSingleton s1 = StaticInnerSingleton.getInstance();
            StaticInnerSingleton s2 = StaticInnerSingleton.getInstance();
            System.out.println(s1 == s2);
    
            EnumSingleton en1 = EnumSingleton.INSTANCE;
            EnumSingleton en2 = EnumSingleton.INSTANCE;
            System.out.println(en1 == en2);
        }
    }
    
    2.测试效率
    /**
     * 测试单例五种方式效率
     */
    public class Client2 {
        public static void main(String[] args) throws InterruptedException {
            Long start = System.currentTimeMillis();
            int threadNum = 10;
            final CountDownLatch countDownLatch = new CountDownLatch(threadNum);
            for(int i=0;i<threadNum;i++){
                new Thread(new Runnable() {
                    @Override
                    public void run() {
    
                        for(int i=0;i<1000000;i++){
    //                        Object o = EagerSingleton.getInstance(); // 耗时52ms
    //                        Object o = LazySingleton.getInstance(); // 耗时342ms
    //                        Object o = DoubleCheckSingleton.getInstance(); // 耗时55ms
    //                        Object o = StaticInnerSingleton.getInstance(); // 耗时54ms
    //                        Object o = EnumSingleton.INSTANCE; // 耗时46ms
                        }
                        countDownLatch.countDown();
                    }
                }).start();
            }
            countDownLatch.await();
            long end = System.currentTimeMillis();
            System.out.println("总耗时:"+(end-start));
        }
    }
    
    3.测试破解
    /**
     * 通过反射和反序列化方式破解单例
     */
    public class Client3 {
        public static void main(String[] args) throws Exception {
            //通过反射方式构造多个对象
            Class<EagerSingletonHack> clazz = (Class<EagerSingletonHack> )Class.forName("cn.dfun.pattern.singleton.EagerSingletonHack");
            Constructor<EagerSingletonHack> c = clazz.getDeclaredConstructor();
            // 构造器设为可见
            c.setAccessible(true);
            EagerSingletonHack e1 = c.newInstance();
            EagerSingletonHack e2 = c.newInstance();
            System.out.println(e1 == e2);
    
            //通过反序列化的方式构造多个对象
            EagerSingletonHack e3 = EagerSingletonHack.getInstance();
            FileOutputStream fos = new FileOutputStream("d:/a.txt");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(e3);
            oos.close();
            fos.close();
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:/a.txt"));
            EagerSingletonHack e4 =  (EagerSingletonHack) ois.readObject();
            System.out.println(e3 == e4);
        }
    }
    
    防破解
    /**
     * 单例模式防破解
     */
    public class EagerSingletonHack implements Serializable {
        private static EagerSingletonHack instance = new EagerSingletonHack();
    
        /**
         * 私有化构造器
         */
        private EagerSingletonHack() {
            // 防止反射方式破解
            if(instance!=null){
                throw new RuntimeException();
            }
        }
    
        public static EagerSingletonHack getInstance() {
            return instance;
        }
    
        /**
         * 反序列化时,如果定义了readResolve()则直接返回此方法指定的对象。而不需要单独再创建新对象!
         * @return
         * @throws ObjectStreamException
         */
        private Object readResolve() throws ObjectStreamException {
            return instance;
        }
    }
    

    2 工厂模式

    使用工厂类创建对象代替new

    简单工厂模式

    定义Car接口

    public interface Car {
        void run();
    }
    

    两个具体实现类

    public class Audi implements Car{
        @Override
        public void run() {
            System.out.println("Audi run...");
        }
    }
    public class Benz implements Car{
        @Override
        public void run() {
            System.out.println("Benz run...");
        }
    }
    

    工厂类根据类型参数返回具体的实现类

    public class CarFactory {
        public static Car createCar(String type) {
            if("Audi".equals(type)) {
                return new Audi();
            } else if("Benz".equals(type)) {
                return new Benz();
            } else {
                return null;
            }
        }
    }
    

    客户端只需与工厂类和接口交互

    public class Client {
        public static void main(String[] args) {
            Car c1 = CarFactory.createCar("Audi");
            Car c2 = CarFactory.createCar("Benz");
            c1.run();
            c2.run();
        }
    }
    
    工厂方法模式

    多个不同工厂类实现相同工厂接口
    Car接口与实现类与1相同
    工厂接口

    public interface CarFactory {
        Car createCar();
    }
    

    两个工厂实现类

    public class AudiFactory implements CarFactory{
        @Override
        public Car createCar() {
            return new Audi();
        }
    }
    public class BenzFactory implements CarFactory{
        @Override
        public Car createCar() {
            return new Benz();
        }
    }
    

    客户端

    public class Client {
        public static void main(String[] args) {
            Car c1 = new AudiFactory().createCar();
            Car c2 = new BenzFactory().createCar();
    
            c1.run();
            c2.run();
        }
    }
    
    抽象工厂模式

    生产不同产品族的所有产品
    引擎接口及高配低配两个实现类

    public interface Engine {
        void run();
    }
    
    class LuxuryEngine implements Engine {
        @Override
        public void run() {
            System.out.println("高配引擎");
        }
    }
    
    class LowEngine implements Engine {
        @Override
        public void run() {
            System.out.println("低配引擎");
        }
    }
    

    座椅接口及低配高配两个实现类

    public interface Seat {
        void massage();
    }
    
    class LuxurySeat implements Seat {
        @Override
        public void massage() {
            System.out.println("高配座椅");
        }
    }
    
    class LowSeat implements Seat {
        @Override
        public void massage() {
            System.out.println("低配座椅");
        }
    }
    

    工厂接口及高配低配两个工厂实现类
    高配工厂创建高配引擎和座椅
    低配工厂创建低配引擎和座椅

    public interface CarFactory {
        Seat createSeat();
        Engine createEngine();
    }
    
    class LuxuryCarFactory implements CarFactory {
        @Override
        public Seat createSeat() {
            return new LuxurySeat();
        }
    
        @Override
        public Engine createEngine() {
            return new LuxuryEngine();
        }
    }
    
    class LowCarFactory implements CarFactory {
        @Override
        public Seat createSeat() {
            return new LowSeat();
        }
    
        @Override
        public Engine createEngine() {
            return new LowEngine();
        }
    }
    

    客户端

    public class Client {
        public static void main(String[] args) {
            CarFactory  factory = new LuxuryCarFactory();
            Engine e = factory.createEngine();
            e.run();
    
            CarFactory  factory2 = new LowCarFactory();
            Seat s = factory2.createSeat();
            s.massage();
        }
    }
    

    3 建造者模式

    复杂对象子组件构建和装配分离
    飞艇类,包含轨道舱\引擎\逃逸塔三个组件

    public class Airship {
        //轨道舱
        private OrbitalModule orbitalModule;
        //发动机
        private Engine engine;
        //逃逸塔
        private EscapeTower escapeTower;
    
        public OrbitalModule getOrbitalModule() {
            return orbitalModule;
        }
    
        public void setOrbitalModule(OrbitalModule orbitalModule) {
            this.orbitalModule = orbitalModule;
        }
    
        public Engine getEngine() {
            return engine;
        }
    
        public void setEngine(Engine engine) {
            this.engine = engine;
        }
    
        public EscapeTower getEscapeTower() {
            return escapeTower;
        }
    
        public void setEscapeTower(EscapeTower escapeTower) {
            this.escapeTower = escapeTower;
        }
    }
    
    class OrbitalModule {
        private String name;
    
        public OrbitalModule(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
    class Engine {
        private String name;
    
        public Engine(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
    class EscapeTower {
        private String name;
    
        public EscapeTower(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    

    构建器接口

    public interface AirshipBuilder {
        Engine builderEngine();
        OrbitalModule builderOrbitalModule();
        EscapeTower  builderEscapeTower();
    }
    

    装配器接口

    public interface AirshipDirector {
        Airship directAirship();
    }
    

    构建器实现类

    public class DfunAirshipBuilder implements AirshipBuilder{
        @Override
        public Engine builderEngine() {
            System.out.println("构建dfun发动机!");
            return new Engine("dfun发动机!");
        }
    
        @Override
        public OrbitalModule builderOrbitalModule() {
            System.out.println("构建dfun轨道舱!");
            return new OrbitalModule("dfun轨道舱!");
        }
    
        @Override
        public EscapeTower builderEscapeTower() {
            System.out.println("构建dfun逃逸塔!");
            return new EscapeTower("dfun逃逸塔!");
        }
    }
    

    装配器实现类

    public class DfunAirshipDirector implements AirshipDirector{
        private AirshipBuilder builder;
    
        public DfunAirshipDirector(AirshipBuilder builder) {
            this.builder = builder;
        }
    
        @Override
        public Airship directAirship() {
            Engine e = builder.builderEngine();
            OrbitalModule o = builder.builderOrbitalModule();
            EscapeTower et = builder.builderEscapeTower();
    
            //装配成飞船对象
            Airship ship = new Airship();
            ship.setEngine(e);
            ship.setEscapeTower(et);
            ship.setOrbitalModule(o);
    
            return ship;
        }
    }
    

    客户端

    public class Client {
        public static void main(String[] args) {
            AirshipDirector director = new DfunAirshipDirector(new DfunAirshipBuilder());
            Airship ship = director.directAirship();
            System.out.println(ship.getEngine().getName());
        }
    }
    

    4 原型模式

    原型模式用于拷贝对象,克隆对象属性值与原对象相同
    spring bean的创建方式就两种:单例和原型

    public class Sheep implements Cloneable, Serializable {
        private String sname;
        private Date birthday;
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            // 直接调用Object对象的clone方法实现克隆
            Object obj = super.clone();
    
            // 深复制
            Sheep s = (Sheep) obj;
            s.birthday = (Date) this.birthday.clone();
    
            return obj;
        }
        getter/setter/有参无参构造器
    }
    

    测试深复制/浅复制

    public class Client {
        public static void main(String[] args) throws CloneNotSupportedException {
            Date d = new Date(123123123123L);
            Sheep s1 = new Sheep("多利", d);
            Sheep s2 = (Sheep)s1.clone();
            // 克隆出的对象与原型对象属性值相同
            System.out.println(s2.getSname());
            // 浅克隆,日期为同一对象
            System.out.println(d == s2.getBirthday());
        }
    }
    

    使用序列化和反序列化的方式实现深克隆

    public class Client2 {
        public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
            Date d = new Date(123123123123L);
            Sheep s1 = new Sheep("多利", d);
    
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(s1);
            byte[] bytes = bos.toByteArray();
    
            ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
            ObjectInputStream ois = new ObjectInputStream(bis);
            Sheep s2 = (Sheep) ois.readObject();
            // 深复制,日期不同
            System.out.println(d == s2.getBirthday());
        }
    }
    

    原型模式效率测试
    对象new过程比较耗时,使用原型模型可以显著提升效率

    public class Client3 {
        public static void testNew(int size) throws InterruptedException {
            long start = System.currentTimeMillis();
            for (int i = 0; i < size; i++) {
                Laptop t = new Laptop();
            }
            long end = System.currentTimeMillis();
            System.out.println(end - start);
        }
    
        public static void testClone(int size) throws InterruptedException, CloneNotSupportedException {
            long start = System.currentTimeMillis();
            Laptop t = new Laptop();
            for (int i = 0; i < size; i++) {
                Laptop temp = (Laptop) t.clone();
            }
            long end = System.currentTimeMillis();
            System.out.println(end - start);
        }
    
        public static void main(String[] args) throws InterruptedException, CloneNotSupportedException {
            testNew(1000);
            testClone(1000);
    
        }
    }
    
    class Laptop implements Cloneable{
        Laptop() throws InterruptedException {
            // 模拟创建对象耗时
            Thread.sleep(10);
        }
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
    

    5 适配器模式

    场景:USB转换头
    将一个类的接口转为客户希望的另一个接口,使原本不兼容的类可以一起工作
    被适配的类

    public class Adaptee {
        public void request() {
            System.out.println("可以完成客户需要的功能");
        }
     }
    
    

    接口

    public interface Target {
        void handleReq();
    }
    

    适配器

    /**
     * 适配器
     * 两种关联方式1.继承 2.持有被适配对象引用
     * @author Vincent
     */
    public class Adapter implements Target{
        private Adaptee adaptee;
    
        public Adapter(Adaptee adaptee) {
            this.adaptee = adaptee;
        }
    
        @Override
        public void handleReq() {
            adaptee.request();
        }
    }
    

    客户端

    public class Client {
        public void test(Target t) {
            t.handleReq();
        }
    
        public static void main(String[] args) {
            Client client = new Client();
            Adaptee adaptee = new Adaptee();
            Target t = new Adapter(adaptee);
            client.test(t);
        }
    }
    

    场景:
    java中流的转换

    6 静态代理模式

    代理模式:
    控制对对象的访问,调用对象方法前做前置处理,调用对象方法后做后置处理
    代理模式是AOP的核心
    场景:
    安全代理,屏蔽真实角色的直接访问
    远程代理,通过代理类处理远程方法调用(RMI)
    延迟加载,先加载轻量级代理对象,真正需要时再加载真实对象
    动态代理:
    动态生成代理类
    JDK自带动态代理\javaassist字节码操作库\CGLIB\ASM(底层指令维护性差)
    接口

    public interface Star {
        /**面谈*/
        void confer();
        /**签合同*/
        void signContract();
        /**订票*/
        void bookTicket();
        /**唱歌*/
        void sing();
        /**收尾款*/
        void collectMoney();
    }
    

    真实类

    public class RealStar implements Star{
        @Override
        public void confer() {
            System.out.println("RealStar confer");
        }
    
        @Override
        public void signContract() {
            System.out.println("RealStar signContract");
        }
    
        @Override
        public void bookTicket() {
            System.out.println("RealStar bookTicket");
        }
    
        @Override
        public void sing() {
            System.out.println("RealStar sing");
        }
    
        @Override
        public void collectMoney() {
            System.out.println("RealStar collectMoney");
        }
    }
    

    代理类

    public class ProxyStar implements Star{
        // 持有真实类的引用
        private Star star;
    
        public ProxyStar(Star star) {
            this.star = star;
        }
    
        @Override
        public void confer() {
            System.out.println("ProxyStar confer");
        }
    
        @Override
        public void signContract() {
            System.out.println("ProxyStar signContract");
        }
    
        @Override
        public void bookTicket() {
            System.out.println("ProxyStar bookTicket");
        }
    
        @Override
        public void sing() {
            // 调用真实类的方法
            star.sing();
        }
    
        @Override
        public void collectMoney() {
            System.out.println("ProxyStar collectMoney");
        }
    }
    
    

    客户端

    public class Client {
        public static void main(String[] args) {
            Star real = new RealStar();
            Star proxy = new ProxyStar(real);
    
            proxy.confer();
            // 代理类调用真实类的方法
            proxy.sing();
        }
    }
    

    7 动态代理模式

    jdk自带动态代理:
    java.lang.reflect.Proxy
    动态生成代理类和对象

    java.lang.reflect.InvocationHandler
    处理器接口
    通过invoke方法实现对真实角色的代理访问
    每次通过Proxy生成代理类对象都要指定对应的处理器对象

    接口

    public interface Star {
        /**唱歌*/
        void sing();
    }
    
    

    真实对象

    public class RealStar implements Star{
        @Override
        public void sing() {
            System.out.println("RealStar sing");
        }
    }
    
    

    处理器对象

    public class StarHandler implements InvocationHandler {
        Star realStar;
    
        public StarHandler(Star realStar) {
            this.realStar = realStar;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // 每次调代理类方法都进到该方法,可进行统一流程控制
            Object object = null;
            System.out.println("面谈...签合同...订机票...");
            if(method.getName().equals("sing")) {
               object =  method.invoke(realStar, args);
            }
            System.out.println("收尾款...");
            return object;
        }
    }
    

    客户端

    public class Client {
        public static void main(String[] args) {
            Star realStar = new RealStar();
            StarHandler handler = new StarHandler(realStar);
            Star proxy = (Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Star.class}, handler);
            proxy.sing();
        }
    }
    

    场景:
    Struts2拦截器
    数据库连接池关闭
    Hibernate延迟加载
    mybatis拦截器插件
    AspectJ
    spring aop 日志/声明式事务
    web service
    RMI
    随便选择一个技术框架都有代理模式

    8 桥接模式

    类膨胀问题
    联想笔记本 联想台式机 联想平板
    华为笔记本 华为台式机 华为平板
    ...
    通过电脑持有品牌对象实现桥接

    /**
     * 品牌
     */
    public interface Brand {
        void sale();
    }
    
    class Lenovo implements Brand {
        @Override
        public void sale() {
            System.out.println("销售联想电脑");
        }
    }
    
    class Dell implements Brand {
        @Override
        public void sale() {
            System.out.println("销售戴尔电脑");
        }
    }
    
    
    public class Computer {
        // 持有品牌对象
        protected Brand brand;
    
        public Computer(Brand brand) {
            this.brand = brand;
        }
    
        public void sale() {
            brand.sale();
        }
    }
    
    class Desktop extends Computer {
    
        public Desktop(Brand brand) {
            super(brand);
        }
    
        @Override
        public void sale() {
            System.out.println("销售台式机");
        }
    }
    
    class Laptop extends Computer {
    
        public Laptop(Brand brand) {
            super(brand);
        }
    
        @Override
        public void sale() {
            System.out.println("销售笔记本");
        }
    }
    
    public class Client {
        public static void main(String[] args) {
            // 销售联想笔记本
            // 用组合代替集成关系
            Computer computer = new Laptop(new Lenovo());
            computer.sale();
        }
    }
    
    

    场景(多个变化维度):
    JDBC

    银行日志管理两个维度
    格式分类 操作 交易 异常
    距离分类 本地 异地

    人力资源系统奖金计算
    奖金分类 个人 团体 激励
    部门分类 人事 销售 研发

    OA消息处理
    业务类型 普通 加急 特急
    发送方式 系统内 短信 邮件

    9 组合模式

    场景

    部分和整体关系用树状结构表示,从而客户端可以使用统一的方式处理部分和整体对象

    模拟杀毒软件架构设计
    public interface AbstractFile {
        void killVirus();
    }
    
    class ImageFile implements AbstractFile {
        private String name;
    
        public ImageFile(String name) {
            this.name = name;
        }
    
        @Override
        public void killVirus() {
            System.out.println("图像文件 " + name + " 进行查杀");
        }
    }
    
    class TextFile implements AbstractFile {
        private String name;
    
        public TextFile(String name) {
            this.name = name;
        }
    
        @Override
        public void killVirus() {
            System.out.println("文本文件 " + name + " 进行查杀");
        }
    }
    
    class Folder implements AbstractFile {
        private String name;
        // 定义容器,用来存放容器子节点
        private List<AbstractFile> list = new ArrayList<>();
    
        public Folder(String name) {
            this.name = name;
        }
    
        public void add(AbstractFile file) {
            list.add(file);
        }
    
        public void remove(AbstractFile file) {
            list.remove(file);
        }
    
        public AbstractFile getChild(int index) {
            return list.get(index);
        }
    
        @Override
        public void killVirus() {
            System.out.println("文件夹 " + name + " 进行查杀");
            for(AbstractFile file : list) {
                // 天然递归
                file.killVirus();
            }
        }
    }
    

    客户端

    public class Client {
        public static void main(String[] args) {
            AbstractFile f2, f3, f5, f6;
            Folder f1 = new Folder("我的收藏");
            f2 = new ImageFile("头像.jpg");
            f3 = new TextFile("1.txt");
    
            f1.add(f2);
            f1.add(f3);
    
    //        f1.killVirus();
    //        f2.killVirus();
    
            Folder f4 = new Folder("图像");
            f5 = new ImageFile("1.jpg");
            f6 = new ImageFile("2.jpg");
            f4.add(f5);
            f4.add(f6);
    
            f1.add(f4);
    
            f1.killVirus();
        }
    }
    
    
    应用

    操作系统资源管理器
    GUI容器层次图
    XML文件解析
    OA组织结构处理
    Junit单元测试框架

    10 装饰器模式

    动态地为一个对象增加新的功能
    无需继承增加子类,使用对象的关联关系,避免类膨胀

    /**
     * 抽象组件
     */
    public interface ICar {
        void move();
    }
    
    /**
     * 具体构建对象
     */
    class Car implements ICar {
    
        @Override
        public void move() {
            System.out.println("陆地上跑");
        }
    }
    
    /**
     * 装饰器对象
     */
    class SuperCar implements ICar {
        protected ICar car;
    
        public SuperCar(ICar car) {
            this.car = car;
        }
    
        @Override
        public void move() {
            car.move();
        }
    }
    
    class FlyCar extends SuperCar {
    
        public FlyCar(ICar car) {
            super(car);
        }
    
        public void fly() {
            System.out.println("飞");
        }
    
        @Override
        public void move() {
            super.move();
            fly();
        }
    }
    
    class WaterCar extends SuperCar {
    
        public WaterCar(ICar car) {
            super(car);
        }
    
        public void swim() {
            System.out.println("游");
        }
    
        @Override
        public void move() {
            super.move();
            swim();
        }
    }
    
    class AICar extends SuperCar {
    
        public AICar(ICar car) {
            super(car);
        }
    
        public void autoMove() {
            System.out.println("自动驾驶");
        }
    
        @Override
        public void move() {
            super.move();
            autoMove();
        }
    }
    

    客户端

    public class Client {
        public static void main(String[] args) {
            Car car = new Car();
            car.move();
    
            // 增加飞行功能
            FlyCar flyCar = new FlyCar(car);
            flyCar.move();
    
            // 增加水里游功能(复合功能)
            WaterCar waterCar = new WaterCar(flyCar);
            waterCar.move();
        }
    }
    
    应用

    IO流
    Servlet API中Request对象HttpServletRequestWrapper(关键词Wrapper)

    缺点

    产生很多小对象,影响性能
    易于出错,调试麻烦

    装饰模式和桥接模式区别

    桥接模式是沿多个维度变化,装饰模式是增加新功能

    11 外观(门面)模式

    迪米特法则:
    一个实体应尽量少地与其他实体发生相互作用

    public class Gongshang {
        public void kaihu() {
            System.out.println("工商局开户");
        }
    }
    
    public class Shuiwu {
        public void baoshui() {
            System.out.println("税务局报税");
        }
    }
    
    public class Yinhang {
        public void kaihu() {
            System.out.println("银行开户");
        }
    }
    

    门面对象

    public class RegisterFacade {
        public void register() {
            Gongshang gongshang = new Gongshang();
            gongshang.kaihu();
            Yinhang yinhang = new Yinhang();
            yinhang.kaihu();
            Shuiwu shuiwu = new Shuiwu();
            shuiwu.baoshui();
        }
    }
    

    客户端

    /**
     * 客户端只与门面对象打交道
     */
    public class Client {
        public static void main(String[] args) {
            RegisterFacade registerFacade = new RegisterFacade();
            registerFacade.register();
        }
    }
    

    各种框架都会用到:
    commons提供的DBUtils类
    Hibernate提供的工具类
    Spring JDBC工具类

    12 享元模式

    很多个相同或相似对象通过享元模式节省内存
    高效支持大量细粒度对象重用

    场景

    围棋棋子,内部状态(颜色)共享,外部状态(坐标)作为参数传入

    /**
     * 享元类
     */
    public interface ChessFlyWeight {
        void setColor(String color);
        String getColor();
        void display(Coordinate c);
    }
    
    class ConcreteChess implements ChessFlyWeight {
        private String color;
    
        public ConcreteChess(String color) {
            this.color = color;
        }
    
        @Override
        public void setColor(String color) {
            this.color = color;
        }
    
        @Override
        public String getColor() {
            return color;
        }
    
        @Override
        public void display(Coordinate c) {
            System.out.println("棋子颜色:" + color);
            System.out.println("棋子坐标:" + c.getX() + "," + c.getY());
        }
    }
    
    public class Coordinate {
        private int x, y;
    
        public Coordinate(int x, int y) {
            this.x = x;
            this.y = y;
        }
    
        public int getX() {
            return x;
        }
    
        public void setX(int x) {
            this.x = x;
        }
    
        public int getY() {
            return y;
        }
    
        public void setY(int y) {
            this.y = y;
        }
    }
    
    

    享元工厂

    /**
     * 享元工厂类
     */
    public class ChessFlyWeightFactory {
        // 享元池
        private static Map<String, ChessFlyWeight> map = new HashMap<>();
    
        public static ChessFlyWeight getChess(String color) {
            if(map.get(color) != null) {
                return map.get(color);
            } else {
                ChessFlyWeight chessFlyWeight = new ConcreteChess(color);
                map.put(color, chessFlyWeight);
                return chessFlyWeight;
            }
        }
    }
    

    客户端

    public class Client {
        public static void main(String[] args) {
            ChessFlyWeight chess1 = ChessFlyWeightFactory.getChess("黑色");
            ChessFlyWeight chess2 = ChessFlyWeightFactory.getChess("黑色");
            System.out.println(chess1 == chess2);
    
            // 增加外部状态处理
            chess1.display(new Coordinate(10, 10));
            chess2.display(new Coordinate(20, 20));
        }
    }
    
    应用

    线程池 数据库连接池
    String类的设计(共享常量池)

    13 责任链模式

    行为模式关注对象交互
    责任链模式将能够处理同一请求的对象连成链

    场景

    打牌轮流出牌
    公司公文审批

    /**
     * 封装请假基本信息
     */
    public class LeaveRequest {
        private String empName;
        private int leaveDays;
        private String reason;
    
       // 有参构造器/getter/setter...
    }
    

    责任链
    关系可以实时修改

    /**
     * 抽象类
     */
    public abstract class Leader {
        protected String name;
        protected Leader nextLeader;
    
        public Leader(String name) {
            this.name = name;
        }
    
        /**
         * 设置责任链后继对象
         * @param nextLeader
         */
        public void setNextLeader(Leader nextLeader) {
            this.nextLeader = nextLeader;
        }
    
        /**
         * 处理请求的核心业务方法
         * @param leaveRequest
         */
        public abstract void handleRequest(LeaveRequest leaveRequest);
    }
    
    class Director extends Leader {
        public Director(String name) {
            super(name);
        }
    
        @Override
        public void handleRequest(LeaveRequest leaveRequest) {
            if (leaveRequest.getLeaveDays() < 3) {
                System.out.println("员工:" + leaveRequest.getEmpName() +
                        "请假, 天数:"+leaveRequest.getLeaveDays());
                System.out.println("主任:" + this.name + "审批通过");
            } else if(this.nextLeader != null) {
                this.nextLeader.handleRequest(leaveRequest);
            }
        }
    }
    
    class Manager extends Leader {
        public Manager(String name) {
            super(name);
        }
    
        @Override
        public void handleRequest(LeaveRequest leaveRequest) {
            if (leaveRequest.getLeaveDays() >= 3 && leaveRequest.getLeaveDays() < 10) {
                System.out.println("员工:" + leaveRequest.getEmpName() +
                        "请假, 天数:"+leaveRequest.getLeaveDays());
                System.out.println("经理:" + this.name + "审批通过");
            } else if(this.nextLeader != null) {
                this.nextLeader.handleRequest(leaveRequest);
            }
        }
    }
    
    class GeneralManager extends Leader {
        public GeneralManager(String name) {
            super(name);
        }
    
        @Override
        public void handleRequest(LeaveRequest leaveRequest) {
            if (leaveRequest.getLeaveDays() >= 10) {
                System.out.println("员工:" + leaveRequest.getEmpName() +
                        "请假, 天数:"+leaveRequest.getLeaveDays());
                System.out.println("总经理:" + this.name + "审批通过");
            } else if(this.nextLeader != null) {
                System.out.println("辞退!");
            }
        }
    }
    

    客户端

    public class Client {
        public static void main(String[] args) {
            Leader a = new Director("张三");
            Leader b = new Manager("李四");
            Leader c = new GeneralManager("王五");
            a.setNextLeader(b);
            b.setNextLeader(c);
            LeaveRequest leaveRequest = new LeaveRequest("Tom", 10, "相亲");
            a.handleRequest(leaveRequest);
        }
    }
    
    

    通过集合\数组生成责任链更加实用
    应用:
    异常机制
    js事件冒泡和捕获机制
    Servlet过滤器
    Struts2拦截器

    14 迭代器(游标 cursor)模式

    场景

    提供一种可以遍历聚合对象的方式

    /**
     * 自定义迭代器接口
     */
    public interface MyIterator {
        void first();
        void next();
        boolean hasNext();
        boolean isFirst();
        boolean isLast();
        Object getCurrent();
    }
    
    /**
     * 自定义聚合类
     */
    public class ConcreteMyAggregate {
        private List<Object> list = new ArrayList<>();
    
        /**
         * 获得迭代器
         * @return
         */
        public MyIterator createIterator() {
            return new ConcreteIterator();
        }
    
        public void addObj(Object obj) {
            list.add(obj);
        }
    
        public void removeObj(Object obj) {
            list.remove(obj);
        }
    
        public List<Object> getList() {
            return list;
        }
    
        public void setList(List<Object> list) {
            this.list = list;
        }
    
        private class ConcreteIterator implements MyIterator {
            private int curcor;
    
            @Override
            public void first() {
                curcor = 0;
            }
    
            @Override
            public void next() {
                if(curcor < list.size()) {
                    curcor++;
                }
            }
    
            @Override
            public boolean hasNext() {
                if(curcor < list.size()) {
                    return true;
                }
                return false;
            }
    
            @Override
            public boolean isFirst() {
                return curcor == 0 ? true : false;
            }
    
            @Override
            public boolean isLast() {
                return curcor == list.size()-1 ? true : false;
            }
    
            @Override
            public Object getCurrent() {
                return list.get(curcor);
            }
        }
    }
    
    public class Client {
        public static void main(String[] args) {
            ConcreteMyAggregate concreteMyAggregate = new ConcreteMyAggregate();
            concreteMyAggregate.addObj("aa");
            concreteMyAggregate.addObj("bb");
            concreteMyAggregate.addObj("cc");
    
            MyIterator iter = concreteMyAggregate.createIterator();
            while(iter.hasNext()) {
                System.out.println(iter.getCurrent());
                iter.next();
            }
        }
    }
    
    
    应用

    Java Set/List的迭代器

    相关文章

      网友评论

          本文标题:设计模式

          本文链接:https://www.haomeiwen.com/subject/hlvdmktx.html