1、构造器私有化
2、类的内部创建对象
3、向外暴露一个静态的公共方法(getInstance)
public class Test01 {
public static void main(String[] args) {
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance1.hashCode()); // 460141958
System.out.println(instance2.hashCode()); // 460141958
System.out.println(instance1 == instance2); // true
}
}
class Singleton {
// 1、构造器私有化,防止外部new
private Singleton() {}
// 2、类的内部创建对象
private final static Singleton instance = new Singleton();
// 3、公开静态返回该单例对象
public static Singleton getInstance() {
return instance;
}
}

推荐但是可能造成内存浪费,不过其实浪费的只有单例这个内存,还是比较可观的
class Singleton {
private Singleton() {}
private static Singleton instance;
// 静态代码块创建单例对象
static {
instance = new Singleton();
}
public static Singleton getInstance() {
return instance;
}
}

1、当主类装载时静态内部类不会被装载
2、当调用静态内部类的方法时会导致静态内部类被装载
class Singleton {
private Singleton() {}
private static class SingletonInstance {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonInstance.INSTANCE;
}
}

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

解决了线程同步问题,但是每次都会进行if判断导致效率较低,可用但是不推荐
class Singleton {
private Singleton() {}
private static Singleton instance;
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}

不能使用如下,假如多个线程进入if判断,会导致同步后仍然创建多个对象,不能使用如下方法
class Singleton {
private Singleton() {}
private static Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
instance = new Singleton();
}
}
return instance;
}
}

class Singleton {
private Singleton() {}
private static volatile Singleton instance;
public static Singleton getInstance() {
// 3、以后的进入都是直接return
if (instance == null) {
// 1、多个线程进入此处同步
synchronized (Singleton.class) {
// 2、第一个进入判断为空则创建,接下来的进入则不会创建
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}

public class Test03 {
public static void main(String[] args) {
Singleton instance1 = Singleton.INSTANCE;
Singleton instance2 = Singleton.INSTANCE;
System.out.println(instance1.hashCode()); // 460141958
System.out.println(instance2.hashCode()); // 460141958
System.out.println(instance1 == instance2); // true
}
}
enum Singleton {
INSTANCE;
}



推荐使用:饿汉式(静态常量、静态代码块)
强烈推荐使用:懒汉式(双重检查)、饿汉式(静态内部类)、枚举

public class SimpleFactory {
public static void main(String[] args) {
Product p1 = Factory.createProduct("A");
Product p2 = Factory.createProduct("B");
p1.info();
p2.info();
}
}
class Factory {
public static Product createProduct(String type) {
Product product = null;
switch (type) {
case "A":
product = new ProductA();
break;
case "B":
product = new ProductB();
break;
// 如果每次添加新的产品都要修改此处,违反开放封闭原则
}
return product;
}
}
abstract class Product {
public abstract void info();
}
class ProductA extends Product {
@Override
public void info() {
System.out.println("产品的信息:A");
}
}
class ProductB extends Product {
@Override
public void info() {
System.out.println("产品的信息:B");
}
}
定义一个用于创建对象的接口,让工厂决定实例化哪一个类,使类的实例化延迟到其子类
缺点:添加新产品时还需要添加对应的工厂类

public class FactoryMethod {
public static void main(String[] args) {
Factory factoryA = new FactoryA();
Product productA = factoryA.createProduct();
productA.info();
Factory factoryB = new FactoryB();
Product productB = factoryB.createProduct();
productB.info();
}
}
interface Factory {
public Product createProduct();
}
class FactoryA implements Factory {
@Override
public Product createProduct() {
return new ProductA();
}
}
class FactoryB implements Factory {
@Override
public Product createProduct() {
return new ProductB();
}
}
interface Product {
public void info();
}
class ProductA implements Product {
@Override
public void info() {
System.out.println("产品的信息:A");
}
}
class ProductB implements Product {
@Override
public void info() {
System.out.println("产品的信息:B");
}
}

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类


如果是添加新的工厂,那么代码的设计非常优秀,但如果是需要生产原先不存在的产品,如生产笔记本,那么需要更改顶层工厂接口
public class Client {
public static void main(String[] args) {
Factory appleFactory = new AppleFactory();
Factory miFactory = new MiFactory();
Pad ipad = appleFactory.createPad();
Phone iphone = appleFactory.createPhone();
ipad.info();
iphone.info();
Pad miPad = miFactory.createPad();
Phone miPhone = miFactory.createPhone();
miPad.info();
miPhone.info();
}
}
工厂接口
// 顶层工厂接口
interface Factory {
public Pad createPad();
public Phone createPhone();
}
入驻的工厂:每个工厂按规矩只能生产平板和手机
// 苹果工厂
class AppleFactory implements Factory {
@Override
public Pad createPad() {
return new Ipad();
}
@Override
public Phone createPhone() {
return new Iphone();
}
}
// 小米工厂
class MiFactory implements Factory {
@Override
public Pad createPad() {
return new MiPad();
}
@Override
public Phone createPhone() {
return new MiPhone();
}
}
产品接口:生产工厂对应的平板和手机
// 平板
interface Pad {
public void info();
}
// 手机
interface Phone {
public void info();
}
产品类
class Ipad implements Pad {
@Override
public void info() {
System.out.println("产品的信息:Ipad");
}
}
class Iphone implements Phone {
@Override
public void info() {
System.out.println("产品的信息:Iphone");
}
}
class MiPad implements Pad {
@Override
public void info() {
System.out.println("产品的信息:MiPad");
}
}
class MiPhone implements Phone {
@Override
public void info() {
System.out.println("产品的信息:MiPhone");
}
}



public class Test01 {
public static void main(String[] args) {
Sheep parent = new Sheep("1", "a");
Sheep s1 = new Sheep(parent.getId(), parent.getName());
Sheep s2 = new Sheep(parent.getId(), parent.getName());
Sheep s3 = new Sheep(parent.getId(), parent.getName());
Sheep s4 = new Sheep(parent.getId(), parent.getName());
}
}


public class Test01 {
public static void main(String[] args) throws CloneNotSupportedException {
Sheep parent = new Sheep("1", "a");
Sheep clone = (Sheep) parent.clone();
System.out.println(parent);
System.out.println(clone);
}
}
class Sheep implements Cloneable {
private String id;
private String name;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class Main {
public static void main(String[] args) {
Product product = new Product(2022, 189);
Product p2 = (Product) product.clone();
System.out.println(product);
System.out.println(p2);
}
}
interface Prototype {
public Object clone();
}
class Product implements Prototype {
private int id;
private double price;
@Override
public Object clone() {
Product product = new Product();
product.id = this.id;
product.price = this.price;
return product;
}
}

public class Person implements Serializable, Cloneable {
private String name;
private Pet pet;
@Override
protected Object clone() throws CloneNotSupportedException {
// 1、克隆基本类型和String类型
Person person = (Person) super.clone();
// 2、克隆引用类型
person.pet = (Pet) pet.clone();
return person;
}
}
public class Pet implements Serializable,Cloneable {
private String name;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public Object deepClone() {
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
try {
// 序列化
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(this);
// 反序列化
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
Person person = (Person) ois.readObject();
return person;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
bos.close();
oos.close();
bis.close();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}


public class Main {
public static void main(String[] args) {
Director director = new Director();
Builder1 builder1 = new Builder1();
director.construct(builder1);
Product p1 = builder1.getResult();
p1.show();
Builder2 builder2 = new Builder2();
director.construct(builder2);
Product p2 = builder2.getResult();
p2.show();
}
}
class Director {
public void construct(Builder builder) {
builder.buildPart();
}
}
abstract class Builder {
public abstract void buildPart();
public abstract Product getResult();
}
class Builder1 extends Builder {
Product product = new Product();
@Override
public void buildPart() {
product.add("双吉堡");
product.add("可乐");
}
@Override
public Product getResult() {
return product;
}
}
class Builder2 extends Builder {
Product product = new Product();
@Override
public void buildPart() {
product.add("鸡肉卷");
product.add("香芋派");
}
@Override
public Product getResult() {
return product;
}
}
class Product {
List<String> parts = new ArrayList<>();
public void add(String part) {
parts.add(part);
}
public void show() {
System.out.println("产品的组成:");
for (String part : parts) {
System.out.print(part + " ");
}
System.out.println("\n");
}
}