B友设计原则笔记:
Java设计原则-优快云博客
创建者模式
单例设计
饿汉式1(静态成员变量)
饿汉式2(静态代码块)
懒汉式1(普通方法)
每次getInstance的时候都会新new一个对象,所以不是同一个对象。改为下面这种就是同个对象了。
懒汉式2(线程安全)
懒汉式3(双重锁)
valatile加在声明的变量instace中
懒汉式4(静态内部类)
静态内部类单例模式中实例由内部类创建,由于JVM在加载外部类的过程中,是不会加载静态内部类的,只有内部类的属性或方法被调用时才会被加载,并初始化其静态属性。静态属性由于被static修饰,保证只被实例化一次,并且严格保证实例化顺序。
枚举方式
(线程安全只会装载一次)饿汉式
public enum test1{
Instance;
}
两次test1.Instance获取到的对象相同
序列化破坏单例化
反序列化破解
反射破坏单例化
反射破解
RunTime类的单例设计模式
简单工厂模式(不遵循开闭原则)
原来在案例中是咖啡店这边去new LatteCoffer对象,原来是咖啡店和咖啡耦合,现在是咖啡工厂和咖啡耦合,使用工厂方法模式则可以解决这个耦合问题
扩展
工厂方法模式
/**
* Description:抽象工厂
*/
public interface CoffeeFactory {
Coffee createCoffee();
}
/**
* Description:具体工厂
*/
public class MsCofferFactory implements CoffeeFactory {
@Override
public Coffee createCoffee() {
return new MsCoffer();
}
}
/**
* Description:具体工厂
*/
public class NtCofferFactory implements CoffeeFactory {
@Override
public Coffee createCoffee() {
return new NtCoffee();
}
}
/**
* Description:抽象咖啡产品
*/
public abstract class Coffee {
public abstract String getName();
public void addSugar() {
System.out.println("加糖");
}
public void addMilk() {
System.out.println("加奶");
}
}
/**
* Description:具体产品
*/
public class MsCoffer extends Coffee{
@Override
public String getName() {
return "美式咖啡";
}
}
/**
* Description:具体产品
*/
public class NtCoffee extends Coffee{
@Override
public String getName() {
return "拿铁咖啡";
}
}
/**
* Description:咖啡店
*/
public class CoffeeStore {
private CoffeeFactory coffeeFactory;
public void setCoffeeFactory(CoffeeFactory coffeeFactory)
{
this.coffeeFactory = coffeeFactory;
}
public Coffee orderCoffee()
{
Coffee coffee = coffeeFactory.createCoffee();
coffee.addMilk();
coffee.addSugar();
return coffee;
}
}
public class test {
public static void main(String[] args) {
CoffeeStore coffeeStore = new CoffeeStore();
coffeeStore.setCoffeeFactory(new MsCofferFactory());
Coffee coffee = coffeeStore.orderCoffee();
System.out.println(coffee.getName());
}
}
抽象工厂模式
//抽象产品
public abstract class Coffee {
public abstract String getName();
public void addSugar() {
System.out.println("加糖");
}
public void addMilk() {
System.out.println("加奶");
}
}
public abstract class Dessert {
public abstract void show();
}
//具体产品
public class MsCoffer extends Coffee {
@Override
public String getName() {
return "美式咖啡";
}
}
public class NtCoffee extends Coffee {
@Override
public String getName() {
return "拿铁咖啡";
}
}
public class Cake extends Dessert{
@Override
public void show() {
System.out.println("巧克力蛋糕");
}
}
//抽象工厂
public interface DessetFactory {
Dessert createDessert();
Coffee createCoffee();
}
//具体工厂
public class UkDessertFactory implements DessetFactory{
@Override
public Dessert createDessert() {
return new Cake();
}
@Override
public Coffee createCoffee() {
return new NtCoffee();
}
}
public class MsDessertFactory implements DessetFactory{
@Override
public Dessert createDessert() {
return new Cake();
}
@Override
public Coffee createCoffee() {
return new MsCoffer();
}
}
//测试
public class test {
public static void main(String[] args) {
// MsDessertFactory factory = new MsDessertFactory();
UkDessertFactory factory = new UkDessertFactory();
Dessert dessert = factory.createDessert();
Coffee coffee = factory.createCoffee();
System.out.println(coffee.getName());
dessert.show();
}
}
模式扩展
原型模式
介绍
案例(浅克隆)
扩展(深克隆)
深克隆:
建造者模式
介绍与案例
优缺点
使用场景
扩展(Builder)
public class Phone {
private String cpu;
private String mainboard;
private String screen;
private Phone(Builder builder) {
this.cpu=builder.cpu;
this.mainboard=builder.mainboard;
this.screen=builder.screen;
}
public static final class Builder {
private String cpu;
private String mainboard;
private String screen;
public Builder cpu(String cpu) {
this.cpu = cpu;
return this;
}
public Builder mainboard(String mainboard) {
this.mainboard = mainboard;
return this;
}
public Builder screen(String screen) {
this.screen = screen;
return this;
}
public Phone build() {
return new Phone(this);
}
}
@Override
public String toString() {
return "Phone{" +
"cpu='" + cpu + '\'' +
", mainboard='" + mainboard + '\'' +
", screen='" + screen + '\'' +
'}';
}
}
public static void main(String[] args) {
Phone phone = new Phone.Builder().
cpu("amd").mainboard("华硕").screen("三星").
build();
System.out.println(phone);
}
创建者各个模式对比
结构性模式
介绍
代理模式
静态代理(卖票):
jdk动态代理(卖票):
因为jdk动态代理是基于接口的,所以代理类必须和原始类实现相同的接口,类加载器用于JVM动态创建代理对象。
这里的proxyFactory不是代理类,它只是一个工厂类,而工厂中提供的一个方法获取的是代理对象,不是代理类。代理类是程序在运行过程中动态的在内存中生成的类。
区别、优缺点、使用场景
适配器模式
类适配器模式(基本不用)
如果没有接口能够实现,那么就只能继承,但是又只能单继承不能多继承,所以无接口时不可用。
对象适配器模式
根据上面案例修改后的类