设计模式

 

设计模式分类

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

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

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

面向对象的设计原则

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

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

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

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

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

创建型模式

工厂模式

简单工厂模式:

抽象工厂模式:

 

 建造者模式

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

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();
    }
}

代理模式

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

 
原文地址:https://www.cnblogs.com/sjp007/p/10348698.html