工厂模式

参考博客地址:https://www.cnblogs.com/yssjun/p/11102162.html

简单工厂模式

简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。

工厂模式

工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现‘开-闭 原则’,实现了可扩展。其次更复杂的层次结构,可以应用于产品结果复杂的场合。
定义一个抽象工厂,其定义了产品的生产接口,但不负责具体的产品,将生产任务交给不同的派生类工厂。

  1. //简单工厂模式接口是void方法
  2. public interface Phone {
  3. void make();
  4. }
  5. //工厂模式是一个返回对象的方法
  6. public interface AbstractFactory {
  7. Phone makePhone();
  8. }

抽象工厂模式

为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
抽象工厂模式通过在AbstarctFactory中增加创建产品的接口,并在具体子工厂中实现新加产品的创建,
当然前提是子工厂支持生产该产品。否则继承的这个接口可以什么也不干。

抽象工厂模式结构

1.抽象工厂
2.具体工厂
3.抽象产品
4.具体产品

1.通过properties配置文件 读取文件
实现依赖倒转

  1. //resource下properties文件名:test
  2. ResourceBundle test = ResourceBundle.getBundle("test");
  3. //properties里存在 path=path=factory.SummerSkinFactory 的一个键值对
  4. Class.forName(test.getString("path")).newInstance();

2.通过xml配置文件 读取文件
解析dom文件的util工具类
https://blog.csdn.net/tanggao1314/article/details/50254929

单例模式

参考博客:https://www.cnblogs.com/huayao/p/6750358.html
只存在一个实体化对象 ,并且可以自行实例化向整个系统提供这个实例

  1. public Class CTO{
  2. //生产一个静态CTO对象 方便别人调用
  3. private static CTO cto = new CTO();
  4. //通过private构造方法限制别人不能创建
  5. private CTO(){
  6. }
  7. //静态方法getinstance 共享CTO
  8. public static cto getInstance() {
  9. return CTO;
  10. }
  11. }

优点

1.内存只有一个实例,减少内存开支,尤其是对象需要频繁创建和销毁时;
2.单例模式只生成一个实例,减少系统的性能开销;
3.单例模式可以避免对资源文件的多重占用;
4.单例模式可以在系统设置全局的访问点,优化和共享资源;

缺点

1.单例模式没有接口不便于扩展;
2.在并发测试中,单例模式不利于代码调试
3.单例模式的功能代码一般写在一个类中,如果设计不合理通常违背了 单一职责原则。

饿汉模式

  1. public static cto getInstance() {
  2. return CTO;
  3. }

懒汉模式

  1. public static cto getInstance(){
  2. if (CTO == null) CTO = new cto();
  3. return CTO;
  4. }

懒汉式单例模式,在低并发的情况下没有问题,但是系统压力增大,并发量增加时,
可能会导致内存出现多个实例,破坏了单例模式最初预想,if (CTO == null) CTO = new cto();这段代码在高并发情况下,第一个线程A执行到CTO = new cto();时,但还没有获得对象。对象初始化需要时间,第二个线程B也在执行,执行到if (CTO == null)判断,那么条件成立,于是也初始化了一个对象。

桥接模式

参考博客:https://www.cnblogs.com/adamjwh/p/9033548.html
在现实生活中,某些类具有两个或多个维度的变化,如图形既可按形状分,又可按颜色分。如何设计类似于 Photoshop 这样的软件,能画不同形状和不同颜色的图形呢?如果用继承方式,m 种形状和 n 种颜色的图形就有 m×n 种,不但对应的子类很多,而且扩展困难
桥接(Bridge)模式的定义如下:将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。

桥接模式结构

  1. 抽象化(Abstraction)角色:定义抽象类,并包含一个对实现化对象的引用。
  2. 扩展抽象化(Refined Abstraction)角色:是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。
  3. 实现化(Implementor)角色:定义实现化角色的接口,供扩展抽象化角色调用。
  4. 具体实现化(Concrete Implementor)角色:给出实现化角色接口的具体实现。

image.png

优点

  • 抽象与实现分离,扩展能力强
  • 符合开闭原则
  • 符合合成复用原则
  • 其实现细节对客户透明

    缺点

    由于聚合关系建立在抽象层,要求开发者针对抽象化进行设计与编程,
    能正确地识别出系统中两个独立变化的维度,这增加了系统的理解与设计难度。

代理模式

参考博客:https://www.cnblogs.com/daniels/p/8242592.html

代理模式结构

  • Subject(抽象主题角色)
  • Proxy(代理主题角色)
  • RealSubject(真实主题角色)

程序设计模式 - 图2

代理模式优缺点

优点:

  1. 能够共同协调调用者和被调用者,在一定程度上降低了系统的耦合度
  2. 客户端可以针对抽象主题角色编程,增加和更换代理类无需修改源代码,符合开闭原则,系统具有较好的灵活性和可拓展性。

缺点:

  1. 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
  2. 实现代理模式需要额外的工作,而且有些代理模式的实现过程较为复制。

    静态代理

    优点:可以做到在符合开闭原则的情况下对目标对象进行功能扩展。
    缺点:我们得为每一个服务都得创建代理类,工作量太大,不易管理。同时接口一旦发生改变,代理类也得相应修改。
  1. public class BuyHouseProxy implements BuyHouse {
  2. private BuyHouse buyHouse;
  3. public BuyHouseProxy(final BuyHouse buyHouse) {
  4. this.buyHouse = buyHouse;
  5. }
  6. @Override
  7. public void buyHosue() {
  8. System.out.println("买房前准备");
  9. buyHouse.buyHosue();
  10. System.out.println("买房后装修");
  11. }
  12. }

动态代理

在动态代理中我们不再需要再手动的创建代理类,我们只需要编写一个动态处理器就可以了。
真正的代理对象由JDK再运行时为我们动态的来创建。
相较于静态代理,动态代理大大减少了我们的开发任务,同时减少了对业务接口的依赖,降低了耦合度。

  1. public class DaoLogHandler implements InvocationHandler {
  2. private Calendar calendar;
  3. private Object object;
  4. public DaoLogHandler(){
  5. }
  6. //传参注入object
  7. public DaoLogHandler(Object object){
  8. this.object=object;
  9. }
  10. @Override
  11. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  12. beforeInvoke();
  13. Object reslut=method.invoke(object,args); //转发调用
  14. afterInvoke();
  15. return reslut;
  16. }
  17. //记录方法调用时间
  18. private void beforeInvoke() {
  19. calendar=new GregorianCalendar();
  20. int hour=calendar.get(Calendar.HOUR_OF_DAY);
  21. int minute=calendar.get(Calendar.MINUTE);
  22. int second=calendar.get(Calendar.SECOND);
  23. String time=hour+":"+minute+":"+second;
  24. System.out.println("调用时间:"+time);
  25. }
  26. private void afterInvoke() {
  27. System.out.println("方法调用结束!");
  28. }
  29. }
public class Client {
    public static void main(String[] args) {
        InvocationHandler handler=null;
        AbstractUserDao userDao=new UserDao();
        handler=new DaoLogHandler(userDao);
        AbstractUserDao proxy=null;

        //动态创建代理对象,用于代理一个AbstractUserDao类型的真实主题对象
        proxy=(AbstractUserDao) Proxy.newProxyInstance(AbstractUserDao.class.getClassLoader(),new Class[]{AbstractUserDao.class},handler);
        proxy.findUserById("001");
    }
}

注意Proxy.newProxyInstance()方法接受三个参数:

  • ClassLoader loader:指定当前目标对象使用的类加载器,获取加载器的方法是固定的
  • Class<?>[] interfaces:指定目标对象实现的接口的类型,使用泛型方式确认类型
  • InvocationHandler:指定动态处理器,执行目标对象的方法时,会触发事件处理器的方法

    虚拟代理

    远程代理

    CGLIB代理

    职责链模式

    参考博客:https://www.cnblogs.com/adamjwh/p/10932216.html
    职责链就是所谓的多级结构,不同级别岗位的职责也有所不同。
    例如员工申请请假,组长只能给你审批一天的假,经理可以给你审批3天的假,更长的假则需要更高级别的审批。
    当请求超过当前角色的职责的时候,它就会向上传递请求。

    职责链模式结构

    image.png
    1.Handler(抽象处理者)
    2.ConcreteHandler(具体处理者)

    观察者模式

    参考博客:https://www.jianshu.com/p/2d5cee8810c0
    观察者模式用于建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其它对象,其它对象将相应做出反应。在观察者模式中发生改变的对象被称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多个观察者,而这些观察者可以没有任何相互联系,可以根据需要增加和删除观察者,使得系统更易于拓展。

    观察者模式结构

    image.png