• 设计模式


     

    设计模式分类

    创建型模式:工厂模式、建造者模式、原型模式、单例模式

    结构型模式:适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式、代理模式

    行为型模式:解释器模式、模板方法模式、责任链模式、命令模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、访问者模式

    面向对象的设计原则

    单一职责原则:一个对象应该只包含单一的指责,并且该指责被完整的封装在一个类中。

    开闭原则:尽量在不修改原有代码的基础上进行拓展。

    里氏代换原则:使用基类对对象进行定义,在运行时再确定其子类类型。

    依赖倒转原则:针对抽象层编程,采用抽象的形式注入。

    合成复用原则:优先使用对象组合(注入),而不是通过继承来达到复用目的。

    创建型模式

    工厂模式

    简单工厂模式:

    抽象工厂模式:

     

     建造者模式

    应用场景:构造的对象复杂,且过程繁琐。

    Builder:给出一个抽象接口,以规范产品对象的各个组成成分的建造。

    ConcreteBuilder:实现Builder接口,具体化复杂对象的各部分创建。

    Director:调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建。

    Product:复杂产品。

    原型模式

    根据原型对象复制创建多个相同或相似的对象,如clone()。

    克隆必须实现Cloneable接口。浅克隆不会复制引用成员,深克隆会复制引用成员。

    package com.sjp.design.create.prototype;
    
    import java.util.ArrayList;
    import java.util.List;
    
    //如果要克隆就必须实现Cloneable接口
    public class Person implements Cloneable{
        private String name;
        private String sex;
        private List<String> list;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    
        public List<String> getList() {
            return list;
        }
    
        public void setList(List<String> list) {
            this.list = list;
        }
    
        //浅克隆
        @Override
        protected Person clone() {
            try {
                Person person = (Person) super.clone();
                return person;
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
                return null;
            }
        }
        //深克隆
    //    @Override
    //    protected Person clone() {
    //        try {
    //            Person person = (Person) super.clone();
    //            List<String> newList = new ArrayList();
    //
    //            for (String str : this.list) {
    //                newList.add(str);
    //            }
    //            person.setList(newList);
    //            return person;
    //        } catch (CloneNotSupportedException e) {
    //            e.printStackTrace();
    //            return null;
    //        }
    //    }
    
        public static void main(String[] args) {
            Person p1 = new Person();
            List<String> list = new ArrayList<String>();
            list.add("123");
            list.add("abc");
            p1.setList(list);
            Person p2 = p1.clone();
            System.out.println(p1 == p2);
            System.out.println(p1.getList() == p2.getList());
        }
    }
    浅克隆:false,true
    深克隆:false,false

    单例模式

    静态变量,静态块是在类被使用的时候初始化的。

    public class Singleton {  
        private static Singleton instance = new Singleton();  
    
        private Singleton (){}  
    
        public static Singleton getInstance() {  
          return instance;  
        }  
    
    }

     结构型模式

    适配器模式

    适配器解决这么一类问题:要访问的方法不再合适的接口里。

    类适配器:访问的接口A中没有想要的方法,接口B中有合适的方法,这是我们可以定义适配器P实现A,继承B。

    对象适配器:同上,适配器P实现A,注入B。

    接口适配器:当存在一个接口定义了N多方法,而我们只想实现其中一到几个,这时可以中间加一层抽象类。

    桥接模式

    桥接模式的用意:将抽象化与实现化解耦,使得二者可以独立的变化。解耦,将两个类继承关系改为聚合关系,就是将强关联改为弱关联。

    优点

    1.分离抽象部分和实现部分,极大提供了系统的灵活性,有助于系统分层,从而产生更好的结构化系统。

    2.抽象和实现可以独立的拓展,互不影响,大大提高了系统的可拓展性。

    桥接模式的结构

    实际场景

    1)实现发送消息,实现方式有短信和邮件。设计如下:

    2)消息又分为加急消息和普通消息,设计如下:

    3)实现特加急消息,设计如下:

    现在出现问题的根本原因,就在于消息的抽象和实现是混杂在一起的,这就导致了一个纬度的变化会引起另一个纬度进行相应的变化,从而使得程序扩展起来非常困难。

    利用桥接模式,如下:

     桥接模式在java中的使用:JDBC驱动器

     装饰器模式

    装饰器模式是使用对象的关联关系代替继承关系,无需通过继承增加子类来扩展对象新功能,更加灵活,避免类型体系的快速膨胀。

    demo:变形金刚在变形前是一辆汽车,它可以在陆地上移动。当它变成机器人之后除了能够在陆地上移动之外,还可以说话;如果需要,它还可以变成飞机,除了在陆地上移动还可以在天空中飞翔。

    Component(抽象构件):Transform.java,声明一个move方法,无论变形金刚如何改变该方法始终都有,是具体构件和抽象装饰类共有的方法。

    package com.sjp.design.create.decorate;
    
    /**
     * Created by Timor on 2019/2/9.
     */
    public interface Transform {
        void move();
    }

    ConcreteComponent(具体构件):Car.java  提供了move方法的实现,运用构造函数初始化输出当前状态,它是一个可以被装饰的类。在这里Car被声明为final类型,说明不能通过继承来拓展其功能,需运用类之间的关联关系来拓展。即装饰器模式

    package com.sjp.design.create.decorate;
    
    /**
     * Created by Timor on 2019/2/9.
     */
    public final class Car implements Transform {
        @Override
        public void move() {
            System.out.println("我会走");
        }
    }

    Decorator(抽象装饰类):Changer.java  定义一个抽象构件类型的transform,通过构造函数或者setter方法来给该对象赋值,同时也通过调用transform对象来实现move方法,这样可以保证原方法不被丢失,而且可以在它的子类中增加新的方法,拓展原有功能。

    package com.sjp.design.create.decorate;
    
    /**
     * Created by Timor on 2019/2/9.
     */
    public abstract class Changer implements Transform{
        private Transform transform;
    
        public Changer(Transform transform) {
            this.transform = transform;
        }
    
        @Override
        public void move() {
            transform.move();
        }
    
        abstract void say();
    }

    ConcreteDecorator(具体装饰类)

    package com.sjp.design.create.decorate;
    
    /**
     * Created by Timor on 2019/2/9.
     */
    public class SayCar extends Changer {
    
        public SayCar(Transform transform) {
            super(transform);
        }
    
        @Override
        void say() {
            System.out.println("我会说");
        }
    }

    AirCar中的air()方法采用半透明,作为一个单独的方法提供给客户端使用,客户端不能使用抽象构件来定义具体装饰对象

    package com.sjp.design.create.decorate;
    
    /**
     * Created by Timor on 2019/2/9.
     * 半透明装饰模式
     */
    public class AirCar extends Changer{
    
        public AirCar(Transform transform) {
            super(transform);
        }
    
        @Override
        void say() {
            System.out.println("我会说");
        }
    
        void fly(){
            System.out.println("我会飞");
        }
    }

    测试:

    package com.sjp.design.create.decorate;
    
    /**
     * Created by Timor on 2019/2/9.
     */
    public class Test {
        public static void main(String[] args) {
            Transform car = new Car();
            car.move();
    
            Changer sayCar = new SayCar(car);
            sayCar.move();
            sayCar.say();
    
            AirCar airCar = new AirCar(car);
            airCar.move();
            airCar.say();
            airCar.fly();
        }
    }

    代理模式

    代理模式使用场景:对原有方法进行改进,采用一个代理类调用原来的方法,且对产生的结果进行控制。

     
  • 相关阅读:
    React Hooks用法大全
    SourceTree3.2.6版本跳过注册办法
    微服务SpringCloud项目架构搭建入门
    参考微信公众平台的加解密接口实现方式
    带有function的JSON对象的序列化与还原
    关于datatables与jquerUI版本冲突问题
    有关于分布式缓存Hazelcast
    bootstrap datepicker含有hasDatepicker无法弹出
    SpringMVC学习系列-后记 解决GET请求时中文乱码的问题
    Spring boot整合Hive
  • 原文地址:https://www.cnblogs.com/sjp007/p/10348698.html
Copyright © 2020-2023  润新知