设计模式
单例模式
定义
确保类中只有一个实例,并且提供一个全局访问点。
实现
- 饿汉式-线程安全
/**
* 饿汉式-线程安全
*/
public class SingleHungry {
/**
* 类初始化的时候就加载这个对象
*/
private static final SingleHungry singleHungry = new SingleHungry();
private SingleHungry() {
}
public static SingleHungry getInstance() {
return singleHungry;
}
}
- 懒汉式-线程不安全
/**
* 懒汉式-线程不安全
*/
public class SingleSlacker {
private static SingleSlacker singleSlacker = null;
private SingleSlacker() {
}
/**
* 运行的时候加载这个对象
* @return
*/
public static SingleSlacker getInstance() {
if (singleSlacker == null) {
singleSlacker = new SingleSlacker();
}
return singleSlacker;
}
}
- 懒汉式-双重同步锁
/**
* 懒汉式-双重同步锁
*/
public class SingleSlackerLock {
private static volatile SingleSlackerLock singleSlackerLock = null;
private SingleSlackerLock() {
}
/**
* 运行时加载
* @return
*/
public static SingleSlackerLock getInstance() {
if (singleSlackerLock == null) {
synchronized (SingleSlackerLock.class) {
if (singleSlackerLock == null) {
singleSlackerLock = new SingleSlackerLock();
}
}
}
return singleSlackerLock;
}
}
优缺点
- 优点
只生成一个实例,对性能的开销比较少,能提高系统效率,同时能严格控制访问。
- 缺点
由于只有一个实例,因此类的职责会过重,同时没有抽象类,扩展有一定局限。
简单工厂
定义
有一个工厂对象决定创建对应的产品实例。
实现
- 定义接口
/**
* 定义接口
*/
public interface ICourse {
/**
* 定义方法
*/
void record();
}
- 定义实现类
/**
* 定义 JavaCourse 类。实现接口
*/
public class JavaCourse implements ICourse {
@Override
public void record() {
System.out.println("Java 课程");
}
}
/**
* 定义 PhpCourse 类。实现接口
*/
public class PhpCourse implements ICourse {
@Override
public void record() {
System.out.println("Php 课程");
}
}
- 定义工厂类
/**
* 定义工厂类,实现对应方法调用
*/
public class CourseFactory {
public ICourse create(String name) {
if ("java".equals(name)) {
return new JavaCourse();
} else if ("php".equals(name)) {
return new PhpCourse();
} else {
return null;
}
}
}
- 测试方法
public class SimpleFactoryTest {
public static void main(String[] args) {
CourseFactory courseFactory = new CourseFactory();
ICourse java = courseFactory.create("java");
java.record();
ICourse php = courseFactory.create("php");
php.record();
}
}
优缺点
- 优点
对客户端隐藏相关细节,只关注结果。
- 缺点
工厂类的职责过重,不利于扩展复杂的产品结构。
工厂方法
定义
定义一个用于创建对象的接口,让子类决定实例化哪一个类。
实现
- 定义抽象类
/**
* 定义抽象类
*/
public abstract class Product {
/**
* 定义公共接口方法
*/
public void publicMethod() {
System.out.println("这是一个公共接口");
}
/**
* 声明抽象方法
*/
public abstract void abstractMethod();
}
- 定义实现类
/**
* 定义具体的类,实现抽线类 Product
*/
public class ConcreteProduct extends Product {
@Override
public void abstractMethod() {
System.out.println("具体类:ConcreteProduct");
}
}
/**
* 定义具体的类,实现抽线类 Product
*/
public class AbstractProduct extends Product {
@Override
public void abstractMethod() {
System.out.println("具体类:AbstractProduct");
}
}
- 定义抽象工厂
/**
* 抽象工厂类,为工厂具体实现类提供扩展
*/
public abstract class Factory {
public abstract <T extends Product> T createProduct(Class<T> t);
}
- 定义抽象工厂的实现类
/**
* 抽象工厂类的实现
*/
public class ConcreteFactory extends Factory {
@Override
public <T extends Product> T createProduct(Class<T> t) {
Product product = null;
try {
product = (T)Class.forName(t.getName()).newInstance();
} catch (Exception e) {
System.out.println("创建失败");
}
return (T)product;
}
}
- 测试类
public class FactoryMethodTest {
public static void main(String[] args) {
// 实例化工厂
Factory factory = new ConcreteFactory();
// 实例 ConcreteProduct 类
ConcreteProduct concreteProduct = factory.createProduct(ConcreteProduct.class);
concreteProduct.publicMethod();
concreteProduct.abstractMethod();
// 实例 AbstractProduct 类
AbstractProduct abstractProduct = factory.createProduct(AbstractProduct.class);
abstractProduct.publicMethod();
abstractProduct.abstractMethod();
}
}
如果去掉抽象工厂类 Factory ,那么就成了简单工厂模式,代码如下:
/** * 简单工厂实现类 */ public class ConcreteFactory { public static <T extends Product> T createProduct(Class<T> t) { Product product = null; try { product = (T)Class.forName(t.getName()).newInstance(); } catch (Exception e) { System.out.println("创建失败"); } return (T)product; } }
优缺点
- 优点
程序的可扩展性比较高。
- 缺点
系统复杂性抽象性难道增加。
动态代理
定义
通过代理对象来调用目标类。
实现
静态代理
- 定义接口
/**
* 定义接口
*/
public interface UserService {
void saveUser();
}
- 定义实现类
/**
* 实现接口,实现类不做任何的操作
*/
public class UserServiceImpl implements UserService {
@Override
public void saveUser() {
System.out.println("用户保存方法");
}
}
- 定义代理类
/**
* 定义代理对象,这里执行对代理对象的操作
* 如果后续增加新的操作,只需要修改对应的实现类即可
*/
public class UserProxy {
private final UserService userService;
public UserProxy(UserService userService) {
this.userService = userService;
}
public void saveUser() {
userService.saveUser();
}
}
- 定义测试类
public class StaticProxyTest {
public static void main(String[] args) {
// 实例化对象 UserService
UserService userService = new UserServiceImpl();
// 实例化代理对象 UserProxy
UserProxy userProxy = new UserProxy(userService);
userProxy.saveUser();
}
}
动态代理
JDK 动态代理
- 引入 pom.xml 文件
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.5</version>
</dependency>
- 定义接口
/**
* 定义接口
*/
public interface UserService {
void saveUser();
}
- 定义实现类
/**
* 实现接口,实现类不做任何的操作
*/
public class UserServiceImpl implements UserService {
@Override
public void saveUser() {
System.out.println("用户保存方法");
}
}
- 定义代理类
public class UserHandler implements InvocationHandler {
private final UserService userService;
public UserHandler(UserService userService) {
this.userService = userService;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(userService, args);
}
}
- 定义测试类
public class DynamicProxyJDKTest {
public static void main(String[] args) {
// 实例化对象
UserService userService = new UserServiceImpl();
// 实例化代理类对象
UserHandler userHandler = new UserHandler(userService);
ClassLoader classLoader = userService.getClass().getClassLoader();
Class<?>[] interfaces = userService.getClass().getInterfaces();
UserService userProxy = (UserService) Proxy.newProxyInstance(classLoader, interfaces, userHandler);
userProxy.saveUser();
}
}
CGLIB 动态代理
- 定义接口
/**
* 定义接口
*/
public interface UserService {
void saveUser();
}
- 定义实现类
/**
* 实现接口,实现类不做任何的操作
*/
public class UserServiceImpl implements UserService {
@Override
public void saveUser() {
System.out.println("用户保存方法");
}
}
/**
* OrderServiceImpl 类没有实现任何接口
*/
public class OrderServiceImpl {
public void saveOrder() {
System.out.println("订单保存方法");
}
}
- 定义代理类
public class UserInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
return methodProxy.invokeSuper(o, objects);
}
}
- 定义测试类
public class DynamicProxyCglibTest {
public static void main(String[] args) {
// 定义动态代理类
Enhancer enhancerUser = new Enhancer();
enhancerUser.setSuperclass(UserServiceImpl.class);
enhancerUser.setCallback(new UserInterceptor());
// 定义被代理的对象
UserService userService = (UserService) enhancerUser.create();
userService.saveUser();
// 定义动态代理类
Enhancer enhancerOrder = new Enhancer();
enhancerOrder.setSuperclass(OrderServiceImpl.class);
enhancerOrder.setCallback(new UserInterceptor());
// 定义被代理的对象
OrderServiceImpl orderService = (OrderServiceImpl) enhancerOrder.create();
orderService.saveOrder();
}
}
优缺点
- 优点
JDK 动态代理,原生 JAVA 支持,不需要任何外部依赖。
CGLIB 动态代理通过继承的方式,无论目标对象有没有实现接口都可以代理。
- 缺点
JDK 动态代理只支持接口的动态代理。
CGLIB 需要引入外部依赖,无法处理 final 的情况。
适配器模式
定义
将一个类的接口转换成另外一个接口。
实现
- 定义需要适配的类
/**
* 需要适配的类
*/
public class AdapterClass {
public void request() {
System.out.println("这是需要适配的类");
}
}
- 定义目标接口
/**
* 目标接口
*/
public interface ObjectiveInterface {
void objectRequest();
}
- 定义适配的类
/**
* 定义适配器类
*/
public class AdapterClassInterface extends AdapterClass implements ObjectiveInterface {
@Override
public void objectRequest() {
super.request();
}
}
- 定义测试类
public class AdapterModelTest {
// 对目标接口的具体实现
public void requestAdapter(ObjectiveInterface objectiveInterface) {
objectiveInterface.objectRequest();
}
public static void main(String[] args) {
AdapterModelTest adapterModelTest = new AdapterModelTest();
AdapterClassInterface adapterClassInterface = new AdapterClassInterface();
// 通过适配器实现调用
adapterModelTest.requestAdapter(adapterClassInterface);
}
}
优缺点
- 优点
程序的高扩展和复用性增加。
- 缺点
过多的适配器使用会使得系统的复杂度增加。
模板模式
定义
一个抽象类中有一个主方法,同时有多个子方法。定义其它的类,继承这个抽象类,重写抽象方法,通过调用抽象类实现子类的调用。
实现
- 定义抽象类
/**
* 定义抽象类
*/
public abstract class TemplateClass {
// 定义接口
public abstract void initialize();
public abstract void start();
public abstract void end();
// 定义模板方法
public final void template() {
initialize();
start();
end();
}
}
- 定义实现类
/**
* 定义实现类 UserService,重写抽象类的方法
*/
public class UserService extends TemplateClass {
@Override
public void initialize() {
System.out.println("user initialize");
}
@Override
public void start() {
System.out.println("user start");
}
@Override
public void end() {
System.out.println("user end");
}
}
/**
* 定义实现类 OrderService,重写抽象类的方法
*/
public class OrderService extends TemplateClass {
@Override
public void initialize() {
System.out.println("order initialize");
}
@Override
public void start() {
System.out.println("order start");
}
@Override
public void end() {
System.out.println("order end");
}
}
- 定义测试类
public class TemplateModelTest {
public static void main(String[] args) {
TemplateClass templateUser = new UserService();
templateUser.initialize();
templateUser.start();
templateUser.end();
TemplateClass templateOrder = new OrderService();
templateOrder.initialize();
templateOrder.start();
templateOrder.end();
}
}
优缺点
- 优点
封装的代码不需要改变,行为有子类控制,有利于代码维护。
- 缺点
每一个不同实现都需要一个子类来实现,会增加系统的复杂度。
观察者模式
定义
定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖的对象皆得到通知并被自动更新。
实现
- 定义观察者接口
/**
* 定义观察者接口 ObserverInterface
*/
public interface ObserverInterface {
void response();
}
- 实现观察者接口
/**
* 实现观察者接口
*/
public class ObserverClass implements ObserverInterface {
@Override
public void response() {
System.out.println("观察者 ObserverClass 收到了消息 ......");
}
}
/**
* 实现观察者接口
*/
public class WatchClass implements ObserverInterface {
@Override
public void response() {
System.out.println("观察者 WatchClass 收到了消息 ......");
}
}
- 定义被观察者接口
/**
* 定义被观察者接口 ObservedInterface
*/
public interface ObservedInterface {
void add(ObserverInterface observer);
void notice();
void change();
}
- 实现被观察者接口
/**
* 实现被观察者接口
*/
public class ObservedClass implements ObservedInterface {
public Vector<ObserverInterface> vector;
@Override
public void add(ObserverInterface observer) {
if (vector == null) {
vector = new Vector<>();
}
this.vector.add(observer);
}
@Override
public void notice() {
for (ObserverInterface observer : vector) {
observer.response();
}
}
@Override
public void change() {
System.out.println("观察者发生了改变 ......");
notice();
}
}
- 定义测试类
public class ObserverModelTest {
public static void main(String[] args) {
ObservedInterface observed = new ObservedClass();
observed.add(new ObserverClass());
observed.add(new WatchClass());
observed.change();
}
}
优缺点
- 优点
完全的开闭原则,支持广播通讯。
- 缺点
无法规避循环依赖导致的系统崩溃。
装饰器模式
定义
在不改变原有对象的基础上,提供了扩展对象功能的方案。
实现
- 定义被装饰对象的接口
/**
* 定义被装饰对象的接口
*/
public interface DecoratorInterface {
void execute();
}
- 实现被装饰对象的接口
/**
* 实现被装饰对象接口
*/
public class DecoratorClass implements DecoratorInterface {
@Override
public void execute() {
System.out.println("这是一个被装饰的类");
}
}
- 定义装饰器类
/**
* 定义装饰器类 Decorator
*/
public class Decorator implements DecoratorInterface {
public DecoratorInterface decoratorInterface;
public Decorator(DecoratorInterface decoratorInterface) {
this.decoratorInterface = decoratorInterface;
}
@Override
public void execute() {
decoratorInterface.execute();
}
}
- 创建具体的装饰器类
/**
* 创建具体的装饰器类
*/
public class DecoratorConcrete extends Decorator{
public DecoratorConcrete(DecoratorInterface decoratorInterface) {
super(decoratorInterface);
}
public void before() {
System.out.println("DecoratorConcrete 前操作");
}
public void after() {
System.out.println("DecoratorConcrete 后操作");
}
public void execute() {
before();
decoratorInterface.execute();
after();
}
}
- 定义测试类
public class DecoratorModelTest {
public static void main(String[] args) {
DecoratorInterface decoratorInterface = new DecoratorClass();
Decorator decorator = new DecoratorConcrete(decoratorInterface);
decorator.execute();
}
}
优缺点
- 优点
比继承灵活,在不改变原有对象的情况下给对象进行扩展。
- 缺点
会增加系统的复杂性。
策略模式
定义
对象有某个行为,在不同的场景中,该行为有不同的实现算法。
实现
- 定义策略模式接口
/**
* 定义策略模式接口
*/
public interface StrategyInterface {
void execute();
}
- 定义策略模式实现类
/**
* 策略接口实现类 StrategyClass
*/
public class StrategyClass implements StrategyInterface {
@Override
public void execute() {
System.out.println("这是策略接口实现类 StrategyClass");
}
}
/**
* 策略接口实现类 StrategyClass
*/
public class StrategicClass implements StrategyInterface {
@Override
public void execute() {
System.out.println("这是策略接口实现类 StrategicClass");
}
}
- 定义策略器的上下文
/**
* 定义策略器的上下文
*/
public class StrategyContext {
private final StrategyInterface strategyInterface;
public StrategyContext(StrategyInterface strategyInterface) {
this.strategyInterface = strategyInterface;
}
public void method() {
strategyInterface.execute();
}
}
- 定义测试类
public class StrategyModelTest {
public static void main(String[] args) {
StrategyContext strategyContext = new StrategyContext(new StrategyClass());
strategyContext.method();
StrategyContext strategyContexts = new StrategyContext(new StrategicClass());
strategyContexts.method();
}
}
优缺点
- 优点
代码耦合性较低,扩展比较方便。
- 缺点
策略的增加会加重系统的复杂性。