设计模式是在前人总结下 , 得出的经验, 设计模式的本质是面向对象设计原则的实际运用,是对类的封装性、继承性和多态性以及类的关联关系和组合关系的充分理解, 接着我们来看设计模式中的两种比较重要的模式 --- 单例模式与工厂模式
目前共有 23 中设计模式 , 根据不同功能可以分为三种类型 : 创建型模式, 结构性模式, 行为型模式
创建型模式:用于描述“怎样创建对象”,它的主要特点是“将对象的创建与使用分离”。提供了单例、原型、工厂方法、抽象工厂、建造者 5 种创建型模式。
结构型模式:用于描述如何将类或对象按某种布局组成更大的结构,提供了代理、 适配器、桥接、装饰、外观、享元、组合 7 种结构型模式。
行为型模式:用于描述类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,以及怎样分配职责。提供了模板方法、策略、命令、职责链、状态、 观察者、中介者、迭代器、访问者、备忘录、解释器 11 种行为型模式。
这里我们主要介绍 : 单例模式与工厂模式
在有些系统中 , 由于为了保持数据的一致性等各种原因, 要求某些类只能创建一个实例 , 这就是单例模式, 具有3 个特点 : 1. 一个实例 2. 只能本类自己创建 3. 向外部提供访问此对象的功能
单例也有两种实现模式 : 分为懒汉式单例和饿汉式单例
饿汉式单例
饿汉式的特点是类加载时直接创建这个实例来供外部访问, 代码示例如下 :
//饿汉式单例
public class Singleton {
//生成唯一实例
private static Singleton singleton = new Singleton();
//私有化构造方法
private Singleton(){ }
//向外提供唯一实例的方法
public static Singleton getInstance(){
return singleton;
}
}
//测试
public class Test {
public static void main(String[] args) {
//拿到的是唯一实例@1b6d3586
Singleton singleton1 = Singleton.getInstance();
System.out.println(singleton1); //@1b6d3586
Singleton singleton2 = Singleton.getInstance();
System.out.println(singleton2); //@1b6d3586
}
}
如上所示, 饿汉式的特点就是在调用 getInstance() 方法之前单例已被创建
懒汉式单例
懒汉式单例则是在第一次调用getInstance() 方法时才创建此实例
//懒汉式单例
public class Singleton {
//声明静态实例
private static Singleton singleton;
//私有化构造方法
private Singleton(){}
//向外提供单例的方法
public synchronized static Singleton getInstance(){
if (singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
public static void main(String[] args) {
// singleton1 与 singleton2为同一实例
Singleton singleton1 = Singleton.getInstance();
System.out.println(singleton1);
Singleton singleton2 = Singleton.getInstance();
System.out.println(singleton2);
}
如上所示 , 懒汉式单例在第一次调用 getInstance() 方法时才会去创建这个实例, 但懒汉式会有线程安全问题 , 所以在方法上直接上了synchronized锁
外界第一次访问懒汉式单例时, 才去创建这个实例, 那么如果此时有两个线程碰巧同时都去调用这个方法, 此时就有可能创建两个实例出来, 所以我们要在方法上加锁, 避免此情况发生
我们一般写程序时, 需要哪个对象就在哪new , 但工厂模式的理念是 : 定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到工厂类当中。这满足创建型模式中所要求的“创建与使用相分离”的特点。
工厂模式按照实现方式又能分为简单工厂模式和抽象工厂模式
简单工厂模式
我们把被创建的对象称为“产品”,把创建产品的对象称为“工厂”。如果要创建的产品不多,只要一个工厂类就可以完成,这种模式叫“简单工厂模式”。 在简单工厂模式中创建实例的方法通常为静态(static)方法,因此简单工厂模式(Simple Factory Pattern)又叫作静态工厂方法模式(Static Factory MethodPattern)
简单工厂里的角色主要有 : 抽象产品 , 具体产品 , 工厂 , 实现如下(例如现在我们要造手机)
抽象产品 : 用于描述所有实例的公共接口
//抽象产品
public interface Product {
void show();
}
具体产品 : 工厂的创建目标
//具体产品A
public class ProductA implements Product{
@Override
public void show() {
System.out.println("具体产品A");
}
}
//具体产品B
public class ProductB implements Product{
@Override
public void show() {
System.out.println("具体产品B");
}
}
工厂 : 简单工厂模式的核心,负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象
public class SimpleFactory {
//创建实例的方法
public static Product createProduct(String className){
if(className == null){
return null;
}else{
try {
// 通过反射机制创建对象
return (Product) Class.forName(className).newInstance();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
}
创建示例如下
public static void main(String[] args) {
Product productA = SimpleFactory.createProduct("SimpleFactoryDemo.ProductA");
Product productB = SimpleFactory.createProduct("SimpleFactoryDemo.ProductB");
}
如果我们要造手机 , 那么就得有手机厂(工厂), 手机就是抽象产品 , 那么具体产品就是苹果手机或者华为手机
抽象工厂模式
简单工厂中我们仅仅造一种产品, 只有产品的抽象, 而抽象工厂则对工厂进行了抽象, 拿上述造手机的例子来说, 就是我们仅仅不在满足只有手机厂, 我现在也需要造路由器厂(部分实现如下)
工厂接口
public interface Factory {
Product createProduct();
}
工厂A和工厂B
//工厂A
public class FactoryA implements Factory{
@Override
public Product createProduct() {
return null;
}
}
//工厂B
public class FactoryB implements Factory{
@Override
public Product createProduct() {
return null;
}
}