1. 程式人生 > 其它 >通過具體業務場景學習工廠模式與策略模式

通過具體業務場景學習工廠模式與策略模式

技術標籤:設計模式設計模式java

  • 入職新公司後熟悉業務過程中收到一個需求,優化一部分程式碼邏輯,優化時考慮業務的複雜性於是就想到使用設計模式優化這部分邏輯,將原來強耦合的邏輯拆分,便於以後的維護,分析之後確定使用工廠模式與策略模式。

  • 先說下具體業務邏輯:首先業務邏輯中物件分為三個維度,分別為單票、大包、批次,每個維度需要執行不同的邏輯,執行邏輯就需要不同的策略來判斷;這裡策略有兩種情況,分別為首次和重算,最後執行的邏輯則是請求其它服務的具體實現。

  • 基於這種場景,首先考慮就是對於維度的拆分,單票、大包、批次都有不同的列舉狀態來判斷,這裡我考慮的就是通過工廠模式判斷列舉值建立物件。第二,對於首次和重算的策略,單票和大包觸發策略的邏輯又不相同,這裡我就考慮使用策略模式首先不同維度下的不同策略的生成。

工廠模式實現:

程式碼如下:

建立通用維度的一個物件Dimension,該物件是一個介面呈現的

public interface Dimension {
    public void create();
}

建立兩個具體的物件Parcel、Container實現Dimension,重寫方法

public class Parcel implements Dimension {
    @Override
    public void create() {
        //具體邏輯
    }
}
public class Container implements Dimension {
@Override public void create() { //具體邏輯 } }
建立工廠及實現類
//建立一個工廠介面,定義一個建立物件的方法
public interface DimensionFactory {
    public Dimension create(Class c) throws ClassNotFoundException, IllegalAccessException, InstantiationException;
}


//建立工廠介面的實現類,用於實現具體的維度物件
public class Factory implements
DimensionFactory { @Override public Dimension create(Class c) throws ClassNotFoundException, IllegalAccessException, InstantiationException { Dimension dimension = (Dimension)Class.forName(c.getName()).newInstance(); return dimension; } }
  • 工廠模式主要實現為建立不同的維度物件,具體需要建立哪個物件不需要我自己去判斷,在工廠中實現這個判斷邏輯,我最終只負責接收建立的物件即可,這也是我對工廠模式的理解。將建立物件的具體業務邏輯封裝在工廠中,使用時只傳遞物件的狀態即可,最終在工廠中會生產出我們想要的物件。並且這樣很好的封裝了業務邏輯,將物件的建立與業務邏輯拆分,由工廠實現即可。

策略模式實現:

策略模式:可以理解為定義多種策略,每種策略都進行封裝,這是物件的一種行為實現。
策略模式實現如下:

建立策略介面
建立具體策略實現類實現策略介面

//策略介面
public interface Tactics {
    void router();
}




//具體策略實現,首次路由策略
public class FirstRouter implements Tactics {
    @Override
    public void router() {
        //首次路由邏輯
    }
}


//具體策略實現,二次路由實現
public class SecondRouter implements Tactics {
    @Override
    public void router() {
        //路由重算邏輯
    }
}

建立封裝策略類,封裝策略的具體實現

//封裝策略,將策略的具體實現進行封裝,禁止外部直接訪問該具體實現過程
public class RouterPackage {
    private Tactics tactics = null;
    public RouterPackage(Tactics tactics) {
        this.tactics = tactics;
    }
    public void toDo() {
        tactics.router();
    }
}

通過業務具體實現過程:

//建立父類介面
public abstract class RouterImpl {
    public abstract void router(long dimensionId);
    
    public void doRouter(long dimensionId,int router) {
        
    }
}



//單票首次路由邏輯:
public class ParcelFirstRouter extends RouterImpl{
    @Override
    public void router(long dimensionId) {
        //實現邏輯
    }
}




//包裹首次路由實現:
public class ContainerFirstRouter extends RouterImpl{
    @Override
    public void router(long dimensionId) {
        //實現邏輯
    }
}

工廠實現:

//建立工廠

public abstract class RouterFactory {
    abstract RouterImpl createRouter(Class c);
}




//工廠實現類實現具體的策略
public class FirstRouterFactory extends RouterFactory
{
    @Override
    RouterImpl createRouter(Class c) {
        RouterImpl router = null;
        try {
            router = (RouterImpl)Class.forName(c.getName()).newInstance();
        }catch (Exception e) {
            e.printStackTrace();
        }
        return router;
    }
}

將生成的策略執行具體的策略邏輯

public class RouterContext {
    private RouterImpl routerImpl;

    public RouterContext(RouterImpl router) {
        this.routerImpl = router;
    }

    public void doRouter(long id) {
        //具體的執行邏輯
    }
}

將工廠模式與策略模式結合實現

public class FactoryAndTactis {
    public void sendRouter(long id) {
        //建立工廠
        ParcelFirstRouterFactory firstRouterFactory = new ParcelFirstRouterFactory();

        DimensionEntity parcel = getDimension(id);
        //執行首次路由
        if (parcel.getType == Dimension.PARCEL_FIRST) {
            //首次路由
            ParcelFirstRouter  parcelFirstRouter = firstRouterFactory.createRouter(ParcelFirstTactis.class);
            RouterContext routerContext = new RouterContext(parcelFirstRouter);
            routerContext.doRouter(parcel.getId);
        } else if (parcel.getType == Dimension.PARCEL_SECOND) {
            //二次路由
        }
    }
}

通過以上實現,工廠模式可以幫助我們生產具體的策略物件,策略模式保證策略物件可以自由的切換而不需要改動其它邏輯,從而達到解耦的目的。如果需要新增一種策略時,直接實現RouterImpl介面即可,無需其它改動。