部分cms平台开发技术基础关键字

1.工厂模式

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

介绍

意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

**主要解决:**主要解决接口选择的问题。

**何时使用:**我们明确地计划不同条件下创建不同实例时。

**如何解决:**让其子类实现工厂接口,返回的也是一个抽象的产品。

**关键代码:**创建过程在其子类执行。

应用实例: 1、您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。 2、Hibernate 换数据库只需换方言和驱动就可以。

优点: 1、一个调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体实现,调用者只关心产品的接口。

**缺点:**每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

使用场景: 1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。 2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。 3、设计一个连接服务器的框架,需要三个协议,“POP3”、“IMAP”、“HTTP”,可以把这三个作为产品类,共同实现一个接口。

**注意事项:**作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度

抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

介绍

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

主要解决:主要解决接口选择的问题。

何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。

如何解决:在一个产品族里面,定义多个产品。

关键代码:在一个工厂里聚合多个同类产品。

优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。

2.单例模式

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

注意

  • 1、单例类只能有一个实例。
  • 2、单例类必须自己创建自己的唯一实例。
  • 3、单例类必须给所有其他对象提供这一实例。

介绍

意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

主要解决:一个全局使用的类频繁地创建与销毁。

何时使用:当您想控制实例数目,节省系统资源的时候。

如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。

关键代码:构造函数是私有的。

优点

  • 1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。
  • 2、避免对资源的多重占用(比如写文件操作)。

缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。

3.依赖注入

依赖注入:组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。容器全权负责的组件的装配,它会把符合依赖关系的对象通过JavaBean属性或者构造函数传递给需要的对象。通过JavaBean属性注射依赖关系的做法称为设值方法注入(Setter Injection);将依赖关系作为构造函数参数传入的做法称为构造器注入(Constructor Injection)

按照执行顺序从上到下:

1.创建PropertyFactory类,getBean方法是为了得到key属性(文件中键的值)

在这里插入图片描述
就是红色框中的名字

package service.factory;

import java.io.InputStream;
import java.util.Properties;

public class PropertyFactory {
    /**
     * 这是创建Bean的工厂方法
     *  key  属性是文件中键的值
     */
    public Object getBean(String key){
        Object obj = null;
        try {
            //获取属性配置文件的输入流
            InputStream input = this.getClass ().getClassLoader ().getResourceAsStream ( "factory.properties" );
            //创建属性集合对象
            Properties prop = new Properties (  );
            //根据属性配置文件的输入把属性中的键值加载进属性集合对象中
            prop.load ( input );
            //根据键取出属性中文件中的值
            String servicename = prop.getProperty ( key );
            //根据配置的类获得反射类
            Class c = Class.forName ( servicename );
            //用反射类的默认构造实例化配置的对象
            obj = c.newInstance ();
        } catch (Exception e) {
            e.printStackTrace ();
        }
        return obj;
    }
}

2.创建SystemContext类以返回PropertyFactory对象:

package tools;

import service.factory.PropertyFactory;

/**
 * 饿汉式:在程序启动或单间模式类被加载的时候,单间模式实例就已经被创建
 */
public class SystemContext {
    private static PropertyFactory factory = new PropertyFactory ();
    public static PropertyFactory getFactory () {
        return factory;
    }
}

3.创建文件:

在这里插入图片描述
4.调用set方法(依赖注入)

 @Override
    public void init () {
        PropertyFactory factory = SystemContext.getFactory();
        //得到Servlet(子类)的反射类
        Class c = this.getClass ();
        //取出当前Servlet(子类)中的方法
        Method[] ms = c.getMethods ();
        try {
            for (Method m : ms){    //迭代所有方法,找出set打头的方法
                String methodName = m.getName ();   //取出当前迭代方法的名字
                //判断是否set开头
                if (methodName.startsWith ( "set" )){
                    //找出后截出set后面的字符串并把第一个字母改为小写
                    String key = methodName.substring ( 3,4 ).toLowerCase ()+methodName.substring ( 4 );
                    //根据约定set方法对应的属性名和属性文件中的key名一致,通过工厂得到产品
                    Object obj = factory.getBean ( key );
                    if (obj != null){
                        //判断是否确实得到产品实例
                        m.invoke ( this,obj );//通过方法反射对象调用当前的set方法的实例
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace ();
        }
    }
发布了101 篇原创文章 · 获赞 49 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Austin_/article/details/100108120