1. 程式人生 > >淺讀elastic-job總結所用設計模式

淺讀elastic-job總結所用設計模式

最近在研讀開源分散式定時任務框架elastic-job原始碼,基本清晰該框架邏輯架構和設計理念,現總結研讀過程中使用到的設計模式。

1. 單例模式

              設計模式中最基本也是最常用的一種,在es-job中使用如下:

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class JobRegistry {
    
    private static volatile JobRegistry instance;
    
    private Map<String, JobScheduleController> schedulerMap = new ConcurrentHashMap<>();
    
    /**
     * 獲取作業登錄檔例項.
     * 
     * @return 作業登錄檔例項
     */
    public static JobRegistry getInstance() {
        if (null == instance) {
            synchronized (JobRegistry.class) {
                if (null == instance) {
                    instance = new JobRegistry();
                }
            }
        }
        return instance;
    }
該單例模式採用雙重檢查鎖進行實現,需要注意靜態例項用volatile關鍵字修飾是很有必要的,如果沒有volatile則該單例模式可能出現多例的情況,原因如下:

volatile(java5):可以保證多執行緒下的可見性;

讀volatile:每當子執行緒某一語句要用到volatile變數時,都會從主執行緒重新拷貝一份,這樣就保證子執行緒的會跟主執行緒的一致。

寫volatile: 每當子執行緒某一語句要寫volatile變數時,都會在讀完後同步到主執行緒去,這樣就保證主執行緒的變數及時更新。

2. 工廠模式和模板模式

原始碼中用到的工廠模式是與模板模式一起使用的,

public static final class LiteJob implements Job {
        
        @Setter
        private ElasticJob elasticJob;
        
        @Setter
        private JobFacade jobFacade;
        
        @Override
        public void execute(final JobExecutionContext context) throws JobExecutionException {
            JobExecutorFactory.getJobExecutor(elasticJob, jobFacade).execute();
        }
    }
public final class JobExecutorFactory {
    
    /**
     * 獲取作業執行器.
     *
     * @param elasticJob 分散式彈性作業
     * @param jobFacade 作業內部服務門面服務
     * @return 作業執行器
     */
    @SuppressWarnings("unchecked")
    public static AbstractElasticJobExecutor getJobExecutor(final ElasticJob elasticJob, final JobFacade jobFacade) {
        if (null == elasticJob) {
            return new ScriptJobExecutor(jobFacade);
        }
        if (elasticJob instanceof SimpleJob) {
            return new SimpleJobExecutor((SimpleJob) elasticJob, jobFacade);
        }
        if (elasticJob instanceof DataflowJob) {
            return new DataflowJobExecutor((DataflowJob) elasticJob, jobFacade);
        }
        throw new JobConfigurationException("Cannot support job type '%s'", elasticJob.getClass().getCanonicalName());
    }
}

此處使用的是簡單工廠模式,通過不同引數生成不同AbstractElasticJobExecutor 例項物件;
public abstract class AbstractElasticJobExecutor {

       .......
	 /**
     * 執行作業.
     */
    public final void execute() {
process(.....);
}
      protected abstract void process(ShardingContext shardingContext);
}

此處使用模板模式,使父類演算法的具體實現延遲到子類,使子類不必改變一個演算法的結構即可重定義該演算法的步驟。

3. 策略模式

策略模式是比較常用的一種設計模式,其設計理念是:定義一系列演算法,將它們一個個封裝起來,並且使他們之間可以相互替換。

在es-job中的使用中是針對不同型別的任務型別設計不同的業務邏輯,其原始碼如下:

public interface JobTypeConfiguration {
    
    /**
     * 獲取作業型別.
     * 
     * @return 作業型別
     */
    JobType getJobType();
    
    /**
     * 獲取作業實現類名稱.
     *
     * @return 作業實現類名稱
     */
    String getJobClass();
    
    /**
     * 獲取作業核心配置.
     * 
     * @return 作業核心配置
     */
    JobCoreConfiguration getCoreConfig(); 
}
public final class SimpleJobConfiguration implements JobTypeConfiguration {
    
    private final JobCoreConfiguration coreConfig;
    
    private final JobType jobType = JobType.SIMPLE;
    
    private final String jobClass;
}
public final class DataflowJobConfiguration implements JobTypeConfiguration {
    
    private final JobCoreConfiguration coreConfig;
    
    private final JobType jobType = JobType.DATAFLOW;
    
    private final String jobClass;
    
    private final boolean streamingProcess;
}

   /**
     * 建立Lite作業配置構建器.
     * 
     * @param jobConfig 作業配置
     * @return Lite作業配置構建器
     */
    public static Builder newBuilder(final JobTypeConfiguration jobConfig) {
        return new Builder(jobConfig);
    }
通過傳入不同的jobConfig物件實現不同型別的任務。


待續。。。