(1)单一职责原则
(2)开闭原则
(3)里氏替换原则LSP
(4)依赖倒转原则
(5)接口隔离原则
(6)迪米特法则
软件设计开发原则的作用
(1)什么是GOF(Gang of Four)
在 1994 年,由 四位作者合称 GOF(全拼 Gang of Four)四⼈合著出版了⼀本名为 Design Patterns - Elements of Reusable Object-Oriented Software.
他们所提出的设计模式主要是基于以下的⾯向对象设计原则。
1)对接⼝编程⽽不是对实现编程。
2)优先使⽤对象组合⽽不是继承
(2)常见的三大设计模式分类
常用:工厂模式、抽象工厂模式、单例模式、建造者模式
不常用:原型模式
常用:适配器模式、桥接模式、装饰器模式、代理模式
不常用:组合模式、外观模式、享元模式
常用:责任链模式、迭代器模式、观察者模式、状态模式、策略模式、模板模式
不常用:备忘录模式、命令模式
几乎不用:访问者模式、中介者模式、解释器模式
(1)简介
(2)使用场景
(3)单例模式分类
(4)实现步骤
(1)第一种方式
public static SingletonLazy getInstance(){
if(instance == null){
instance = new SingletonLazy();
}
return instance;
}
(2)第二种方式
public static synchronized SingletonLazy getInstance(){
if(instance == null){
instance = new SingletonLazy();
}
return instance;
}
(3)第三种方式
public static SingletonLazy getInstance(){
if(instance == null){
synchronized (SingletonLazy.class){
instance = new SingletonLazy();
}
}
return instance;
}
(4)第四种方式
DCL双重检查锁定(Double-Checked-Locking),多线程下保持高性能
instrance = new SingletonLazy(),并不是原子性操作,衍生到内存模型
volatile禁止指令重排
private static volatile SingletonLazy instance;
public static SingletonLazy getInstance(){
if(instance == null){
synchronized (SingletonLazy.class){
if(instance == null){
instance = new SingletonLazy();
}
}
}
return instance;
}
(5)测试
public class SingletonLazy{
private static volatile SingletonLazy instance;
private SingletonLazy(){
};
public static SingletonLazy getInstance(){
if(instance == null){
synchronized (SingletonLazy.class){
//1
if(instance == null){
//2
instance = new SingletonLazy(); //3
}
}
}
return instance;
}
public void pub(){
System.out.println("方法调用");
}
}
1.线程A进入 getInstance() 方法。
2.由于 singleton为 null,线程A在 //1 处进入 synchronized 块。
3.线程A被线程B预占。
4.线程B进入 getInstance() 方法。
5.由于 singleton仍旧为 null,线程B试图获取 //1 处的锁。然而,由于线程A已经持有该锁,线程B在 //1 处阻塞。
6.线程B被线程A预占。
7.线程A执行,由于在 //2 处实例仍旧为 null,线程A还创建一个 Singleton 对象并将其引用赋值给 instance。
8.线程A退出 synchronized 块并从 getInstance() 方法返回实例。
9.线程A被线程B预占。
10.线程B获取 //1 处的锁并检查 instance 是否为 null。
11.由于 singleton是非 null 的,并没有创建第二个 Singleton 对象,由线程A所创建的对象被返回。
public class Main {
public static void main(String[] args) {
SingletonLazy.getInstance().pub();
}
}
public class SingletonHungry{
//提前new好,jvm加载时创建
private static SingletonHungry instance = new SingletonHungry();
//构造私有化
private SingletonHungry(){
};
public static SingletonHungry getInstance(){
return instance;
}
public void pub(){
System.out.println("方法调用");
}
}
(1)简介
(2)工厂模式的三种实现方式
(3)应用场景
(1)简介
(2)核心组成
Factory:工厂类,简单工厂模式的核心,它负责实现创建所有的内部逻辑。
IProduct:抽象产品类,简单工厂模式所创建的所有对象的父接口,描述所有实例共有的公共方法。
Product:具体产品类,是简单工厂模式的创建目标。
(3)实现步骤
(4)编码实现
public interface Pay {
/**
* 统一下单接口
*/
void unifiedOrder();
}
public class WechatPay implements Pay{
@Override
public void unifiedOrder() {
System.out.println("微信支付统一下单接口");
}
}
public class AliPay implements Pay {
@Override
public void unifiedOrder() {
System.out.println("支付宝支付统一下单接口");
}
}
public class SimplePayFactory {
public static Pay createPay(String payType){
if(payType == null){
return null;
}
if("WECHAT_PAY".equalsIgnoreCase(payType)){
return new WechatPay();
}else if("ALI_PAY".equalsIgnoreCase(payType)){
return new AliPay();
}
//扩展更多
return null;
}
}
public static void main(String[] args) {
Pay pay = SimplePayFactory.createPay("ALI_PAY");
pay.unifiedOrder();
}
(5)类图关系
(6)优点和缺点
(1)简介
工厂方法模式又称工厂模式,是对简单工厂模式的进一步抽象化,其好处是可以使系统在不修改原来代码的前提下引进新的产品,既满足开闭原则。
通过工厂父类定义负责创建产品的公共接口,通过子类来确定所需创建的类型。
相比简单工厂而言,此种方法具有更多的可扩展性和复用性,同时也增强了代码的可读性。
将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化哪一个类。
(2)核心组成
(3)编码实现
public interface PayFactory {
Pay createPay();
}
public class AliPayFactory implements PayFactory {
@Override
public Pay createPay() {
return new AliPay();
}
}
public class WechatPayFactory implements PayFactory {
@Override
public Pay createPay() {
return new WechatPay();
}
}
public static void main(String[] args) {
PayFactory pay = new AliPayFactory();
pay.createPay().unifiedOrder();
}
(4)类关系图
创建支付接口Pay。
创建支付实现类AliPay、WechatPay。
创建支付创建工厂PayFactory。
创建工厂创建实现类AliPayFactory、WechatPayFactory。
客户端生产某个支付类,直接new 具体支付工厂类即可。
(5)优点和缺点
(1)简介
(2)背景
(3)实现步骤
1.定义两个接口 Pay、Refund。
2.创建具体的Pay产品、创建具体的Refund产品。
3.创建抽象工厂OrderFactory接口,里面两个方法createPay、createRefund。
4.创建支付宝产品族AliOrderFactory,实现OrderFactory抽象工厂。
5.创建微信支付产品族WechatOrderFactory,实现OrderFactory抽象工厂。
6.定义一个超级工厂创造器,通过传递参数获取对应的工厂。
(4)类关系图
抽象工厂涉及到产品族,一个工厂创建这一族的所有产品。
创建支付接口,生产支付具体类,PayFactory,定义抽象方法统一下单方法unifiedOrder()。
创建支付实现类,实现PayFactory接口,实现具体的unifiedOrder()方法,AliPay、WechatPay。
创建退款接口,生产退款具体类,RetundFactory,定义抽象方法统一退款方法retund()。
创建退款实现类,实现RetundFactory接口,实现具体的retund()方法,AliRetund、WechatRetund。
定义OrderFactory,订单工厂中包含订单的支付createPay、订单退款createRetund()。
创建AliOrderFactory、WechatOrderFactory实现OrderFactory中的createPay()、createRetund()方法。
AliOrderFactory、WechatOrderFactory分别返回对应的支付、退款方法。
创建超级工厂类,传入参数返回相应的订单工厂实现类。
(5)编码实现
public interface OrderFactory {
PayFactory createPay();
RefundFactory createRefund();
}
public interface Pay {
/**
* 统一下单接口
*/
void unifiedOrder();
}
public interface Refund {
/**
* 退款
*/
void refund();
}
public class AliOrderFactory implements OrderFactory {
@Override
public PayFactory createPay() {
return new AliPay();
}
@Override
public RefundFactory createRefund() {
return new AliRefund();
}
}
public class AliPay implements PayFactory {
@Override
public void unifiedOrder() {
System.out.println("支付宝支付统一下单接口");
}
}
public class AliRefund implements RefundFactory {
@Override
public void refund() {
System.out.println("支付宝退款");
}
}
public class WechatOrderFactory implements OrderFactory {
@Override
public PayFactory createPay() {
return new WechatPay();
}
@Override
public RefundFactory createRefund() {
return null;
}
}
public class WechatPay implements PayFactory {
@Override
public void unifiedOrder() {
System.out.println("微信支付统一下单接口");
}
}
public class WechatRefund implements RefundFactory {
@Override
public void refund() {
System.out.println("微信退款");
}
}
public class FactoryProducer {
public static OrderFactory getFactory(String type){
if("WECHAT".equalsIgnoreCase(type)){
return new WechatOrderFactory();
}else if("ALI".equalsIgnoreCase(type)){
return new AliOrderFactory();
}
return null;
}
}
OrderFactory ali = FactoryProducer.getFactory("ALI");
ali.createPay().unifiedOrder();
ali.createRefund().refund();
(6)优点和缺点
(1)简介
(2)核心组成
(3)应用场景
(4)深浅拷贝
浅拷贝实现 Cloneable,深拷贝是通过实现 Serializable 读取二进制流
浅拷贝
如果原型对象的成员变量是基本数据类型(int、double、byte、boolean、char等),将复制一份给克隆对象。
如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址。
通过覆盖Object类的clone()方法实现浅克隆
无论原型对象的成员变量是基本数据类型还是引用数据类型,都将复制一份给克隆对象,如果需要实现深克隆,可以通过序列化(serializable)等方式来实现。
(1)编码实现
编写Person实体,浅克隆实现Cloneable,深克隆实现Serializable
public class Person implements Cloneable, Serializable {
private String name;
private int age;
private List<String> list = new ArrayList<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
//浅克隆方法
@Override
public Person clone() throws CloneNotSupportedException {
return (Person)super.clone();
}
//深克隆方法
public Object deepClone(){
try{
//输出 序列化
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
//输入 反序列化
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
Person copyObj = (Person)ois.readObject();
return copyObj;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
@Override
public String toString() {
return "Persion{" +
"name='" + name + '\'' +
", age=" + age +