23种设计模式(特点、应用、实例)

**

持续更新中······

**

今年注定是不容易的一年,很多人基本都是在家上课的。

而我,也迎来了自己的毕业季。在匆匆忙忙的回校收拾后,匆匆忙忙的回到了自己的工作。

在这个过程中,找到了大学期间写下的一本笔记,设计模式。满满都是回忆,我也希望把它分享给其他人。故此,写下这篇文章。

创建型模式

  1. 工厂方法模式(定义一个创建对象的接口,但由子类决定要实例化的类是哪一个,单产品系)

    1.1 特点
    1.1.1 把类的实例化延迟到子类
    1.1.2 一个工厂对应生产一个产品
    1.2 应用
    1.2.1 如读取不同的文件,可以有文本文件工厂或是图像文件工厂
    1.2.2 客户端无需知道具体的产品类,只需要知道其所对应的工厂即可

    1.3 实例

	// 产品
	public interface ICar {}
	public class MidCar implements ICar {}
	public class UpCar implements ICar {}
	// 抽象工厂
	public abstract class AbstractFactory {
	
	    public abstract ICar create();
	}
	// 实例工厂
	public class MidCarFactory extends AbstractFactory {
	
	    @Override
	    public ICar create() {
	        return new MidCar();
	    }
	}
	public class UpCarFactory extends AbstractFactory {
	
	    @Override
	    public ICar create() {
	        return new UpCar();
	    }
	}
  1. 抽象工厂模式(提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类,多产品系)

    2.1 特点
    2.1.1 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象
    2.1.2 产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象工厂加代码,也要在工厂生产者里加代码
    2.2 应用
    2.2.1 系统换皮肤,一整套一起换
    2.2.2 生成不同操作系统的程序

    2.3 实例

	// 车产品
	public interface ICar {}
	public class MidCar implements ICar {}
	public class UpCar implements ICar {}
	// 颜色产品
	public interface IColor {}
	public class RedColor implements IColor {}
	public class BlueColor implements IColor {}
	// 抽象工厂
	public abstract class AbstractFactory {
	
	    public abstract ICar createMidCar() throws Exception;
	    public abstract ICar createUpCar() throws Exception;
	    public abstract IColor fillRed() throws Exception;
	    public abstract IColor fillBlue() throws Exception;
	}
	// 车工厂,生产除车外的产品,会抛出自定义异常
	public class CarFactory extends AbstractFactory {
	
	    @Override
	    public ICar createMidCar() throws Exception {
	        return new MidCar();
	    }
	    @Override
	    public ICar createUpCar() throws Exception {
	        return new UpCar();
	    }
	    @Override
	    public IColor fillRed() throws Exception {
	        throw new CqException("Please use ColorFactory to create!");
	    }
	    @Override
	    public IColor fillBlue() throws Exception {
	        throw new CqException("Please use ColorFactory to create!");
	    }
	}
	// 颜色工厂,生产除颜色外的产品,会抛出自定义异常
	public class ColorFactory extends AbstractFactory {
	
		@Override
	    public IColor fillRed() throws Exception {
	        return new RedColor();
	    }
	    @Override
	    public IColor fillBlue() throws Exception {
	        return new BlueColor();
	    }
	    @Override
	    public ICar createMidCar() throws Exception {
	        throw new CqException("Please use CarFactory to create!");
	    }
	    @Override
	    public ICar createUpCar() throws Exception {
	        throw new CqException("Please use CarFactory to create!");
	    }
	}
	
  1. 单例模式(自己创建唯一实例,并对外提供获取这唯一实例的方法)

    3.1 特点
    3.1.1 单例类只能有一个实例
    3.1.2 单例类必须自己创建自己的唯一实例
    3.1.3 单例类必须给所有其它对象都能提供这一实例
    3.2 应用
    3.2.1 日志类
    3.2.2 配置文件信息单例类
    3.2.3 应用服务器单例类(spring bean默认单例)

    3.3 实例

    /**
     * 最佳延迟实例化
     * 
     * 单例类
     * @author CQJames 2020-06-13
     */
    public class Singleton {
    
        /**
         * 第一次调用后,JVM才会加载Helper内部类,并初始化SINGLETON
         *
         * 实现线程安全
         * 1、利用static初始化数据,保证数据在内存中是独一份的
         * 2、利用final变量在初始化完成之后就无法被修改的特点
         */
        public static Singleton getInstance() {
            return Helper.SINGLETON;
        }
    
        private static class Helper {
            private static final Singleton SINGLETON = new Singleton();
        }
    
        private Singleton() {}
    }
    
  2. 建造者模式(将复杂的构建与其表示相分离,使得相同的构建过程可以创建不同的表示)

    4.1 特点
    4.1.1 各个具体的建造者相互独立,有利于系统的扩展
    4.1.2 调用者不必知道产品内部构建的细节,有利于减少细节风险
    4.1.3 如果产品的内部变化复杂,会增加很多的建造者类
    4.2 应用
    4.2.1 初始化一个对象时,其参数过多,或者有很多参数都具有默认值
    4.2.2 隔离复杂对象的创建和使用,相同的方法但不同的执行顺序,产生不同的事件结果
    4.2.3 需要生成的产品对象有复杂的内部结构,这些产品对象具备共性

    4.3 实例

    /**
     * 自带建造者(除了必须字段,其它字段是可选的,易于自己选择不同的表示)
     * 
     * 发送邮件参数
     * @author CQJames 2019-12-28
     */
    public class SendEmailParams {
    
        // 收件人邮箱,支持多个,用英文逗号隔开
        private final String to;
        // 发件人账号和密码
        private final EmailAccount emailAccount;
        // 抄送,支持多个,用英文逗号隔
        private final String cc;
        // 秘密抄送,支持多个,用英文逗号隔开
        private final String bcc;
        // 邮件标题
        private final String subject;
        // 邮件正文
        private final String body;
        // 邮件内容编码,默认utf-8
        private final String encoding;
        // 附件列表,每个元素包含fileName和content两个字段
        private final List<Attachment> attachments;
    
        private SendEmailParams(Builder builder) {
            this.to = builder.to;
            this.emailAccount = builder.emailAccount;
            this.cc = builder.cc;
            this.bcc = builder.bcc;
            this.subject = builder.subject;
            this.body = builder.body;
            this.encoding = builder.encoding;
            this.attachments = builder.attachments;
        }
    
        public static class Builder {
            // 必须的参数
            private final String to;
            private final EmailAccount emailAccount;
    
            // 可选参数
            private String cc = "";
            private String bcc = "";
            private String subject = "";
            private String body = "";
            private String encoding = "";
            private List<Attachment> attachments = new ArrayList<Attachment>();
    
            public Builder(String to, EmailAccount emailAccount) {
                this.to = to;
                this.emailAccount = emailAccount;
            }
    
            public Builder cc(String cc) {
                this.cc = cc;
                return this;
            }
    
            public Builder bcc(String bcc) {
                this.bcc = bcc;
                return this;
            }
    
            public Builder subject(String subject) {
                this.subject = subject;
                return this;
            }
    
            public Builder body(String body) {
                this.body = body;
                return this;
            }
    
            public Builder encoding(String encoding) {
                this.encoding = encoding;
                return this;
            }
    
            public Builder attachments(List<Attachment> attachments) {
                this.attachments = attachments;
                return this;
            }
    
            public SendEmailParams build() {
                return new SendEmailParams(this);
            }
        }
    }
    
    
  3. 原型模式(原型实例决定了创建的对象,并且通过复制原型创建出新的对象)

    5.1 特点
    5.1.1 提高创建对象的性能,避免了new对象
    5.1.2 必须实现 Cloneable 接口
    5.2 应用
    5.2.1 通过 new 产生一个对象需要非常繁琐的数据准备或访问权限
    5.2.2 浅复制,实现Cloneable接口,重写clone方法,调用super.clone()
    5.2.3 深复制,复制对象源类实现Cloneable接口和Serializable接口,级联串复制对象都要实现Serializable接口接口。

    5.3 实例

    public class Address implements Serializable {}
    /**
     * 深复制实例
     *
     * @author CQJames 2020-07-12
     */
    public class Student implements Cloneable, Serializable {
    
    	private Address address;
    	
        @Override
        protected Object clone() throws CloneNotSupportedException {
    
            Object cloneInstance = null;
            try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
                    ObjectOutputStream oos = new ObjectOutputStream(bos)) {
                // 将对象写到流中
                oos.writeObject(this);
                try (ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
                        ObjectInputStream ois = new ObjectInputStream(bis)) {
                    // 从流中读回来
                    cloneInstance = ois.readObject();
                } catch (IOException | ClassNotFoundException e) {
                    e.printStackTrace();
                }
            } catch (IOException  e) {
                e.printStackTrace();
            }
            return cloneInstance;
        }
    
    }
    /**
     * 原型管理器
     *
     * 线程安全
     * 私有化构造器
     * @author CQJames 2020-07-12
     */
    public class PrototypeManager {
    
        private Map<String, Object> storePrototypeMap = new ConcurrentHashMap<>();
    
        private static PrototypeManager prototypeManager = new PrototypeManager();
    
        public static PrototypeManager getInstance() {
            return prototypeManager;
        }
    
        public void addPrototype(String key, Object prototype) {
            storePrototypeMap.put(key, prototype);
        }
    
        public Object getPrototype(String key) {
            return storePrototypeMap.get(key);
        }
    
        private PrototypeManager() {}
    }
    

结构型模式

  1. 适配器模式
  2. 装饰模式
  3. 代理模式
  4. 外观模式
  5. 桥接模式
  6. 组合模式
  7. 享元模式

行为型模式

  1. 策略模式

  2. 模板方法模式

  3. 观察者模式

  4. 迭代器模式

  5. 责任链模式(对请求的发送者和接收者进行解耦)

    5.1 特点
    5.1.1 降低模块之间的耦合度
    5.1.2 不能保证请求一定被接收
    5.2 应用
    5.2.1 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时确定
    5.2.2 可动态指定一组对象处理请求

    5.3 实例

	public class Request {}
	public class Response {}
	public interface Filter {
	
	    void doFilter(Request request, Response response, Chain chain);
	}
	/**
	 * 驱动责任链传递
	 */
	public interface Chain {
	
	    void handle(Request request, Response response);
	}
	/**
	 * 责任链实例
	 *
	 * @author CQJames 2020-07-13
	 */
	public class FilterChain implements Chain {
	
	    private Queue<Filter> filterQueue = new LinkedList<>();
	
	    public FilterChain addFilter(Filter filter) {
	
	        filterQueue.offer(filter);
	        return this;
	    }
	
	    @Override
	    public void handle(Request request, Response response) {
	
	        if (filterQueue.isEmpty()) {
	            return;
	        }
	        Filter filter = filterQueue.poll();
	        filter.doFilter(request, response, this);
	    }
	}
	public class OneFilter implements Filter {
	
	    @Override
	    public void doFilter(Request request, Response response, Chain chain) {
	
	        chain.handle(request, response);
	    }
	}
  1. 命令模式
  2. 备忘录模式
  3. 状态模式
  4. 访问者模式
  5. 中介者模式
  6. 解释器模式
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值