日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

架構模式是軟件架構中在給定環境下常遇到問題的通用的、可重用的解決方案。類似于軟件設計模式但覆蓋范圍更廣,致力于軟件工程中不同問題,如計算機硬件性能限制、高可用性、業務風險極小化。一些架構模式在軟件框架被實現。- 維基百科

說明

架構模式有很多種,本文只討論工作中使用較多的幾種:

  • 分層架構
  • Pipeline架構
  • 事件驅動架構

 

分層架構

淺談常用的架構模式

分層架構模式

分層架構模式工作中用的比較多,常見的有MVC等,通過分層將職責劃分到某一層上,層次清晰,架構明了。

我們以MVC來舉例說明:controller -> service -> dao

@RestController
@RequestMApping("/order")
public class OrderController {
    @Autowired
    private OrderService orderService;

    /**
     * 新增訂單
     * @param order
     * @return
     */
    @PostMapping("/add")
    public Response addOrder(Order order) {
        orderService.add(order);
        return Response.success();
    }
}
public interface OrderService {
    /**
     *  添加訂單
     * @param order
     * @return
     */
    boolean add(Order order);
}
public interface OrderRepository {

    int save(Order order);
}

按照依賴方向,上層依次依賴下層,每一層處理不同到邏輯。

之前到文章有討論過通過依賴反轉來改變依賴關系,從而更少到減少耦合。

 

Pipeline架構

淺談常用的架構模式

Pipeline架構模式

Pipeline架構也稱為管道或流水線架構,處理流程成線性,各個環節有相應到組件處理,從前到后順序執行。

概念說明:

source: 數據源,通常使用流數據為源,比如:KafkaSource;

channel:信道或管道,用于處理或轉換數據,比如:JsonChannel;

Sink:數據落地,通常用于數據存儲或轉發,比如:DbSink, KafkaSink;

Component: 組件,用于執行邏輯的最小單元,source,channel,sink都是一個Component;

Pipeline: 管道或流水線,一個Pipeline由上面的組件組成,不同的業務可以組裝成不同的Pipeline;

 

代碼實現:數字數據源 -> 累加 -> 轉成字符串 -> 落地

/**
 *  組件
 */
public interface Component<T> {
    /**
     *  組件名稱
     * @return
     */
    String getName();

    /**
     *  獲取下游組件
     * @return
     */
    Collection<Component> getDownStrems();

    /**
     *  組件執行
     */
    void execute(T o);
}
public abstract class AbstractComponent<T, R> implements Component<T>{

    @Override
    public void execute(T o) {
        // 當前組件執行
        R r = doExecute(o);
        System.out.println(getName() + " receive " + o + " return " + r);
        // 獲取下游組件,并執行
        Collection<Component> downStreams = getDownStrems();
        if (!CollectionUtils.isEmpty(downStreams)) {
            downStreams.forEach(c -> c.execute(r));
        }
    }

    protected abstract R doExecute(T o);
}
/**
 *  數據來源
 */
public abstract class Source<T, R> extends AbstractComponent<T, R>{

}
/**
 *  管道/信道
 * @param <T>
 */
public abstract class Channel<T, R> extends AbstractComponent<T, R> {

}
/**
 *  數據落地
 * @param <T>
 */
public abstract class Sink<T, R> extends AbstractComponent<T, R> {

}
public class IntegerSource extends Source<Integer,  Integer>{

    @Override
    protected Integer doExecute(Integer o) {
        return o;
    }

    @Override
    public String getName() {
        return "Integer-Source";
    }

    @Override
    public Collection<Component> getDownStrems() {
        return Collections.singletonList(new IncrChannel());
    }

}
public class IncrChannel extends Channel<Integer, Integer> {

    @Override
    protected Integer doExecute(Integer o) {
        return o + 1;
    }

    @Override
    public String getName() {
        return "Incr-Channel";
    }

    @Override
    public Collection<Component> getDownStrems() {
        return Collections.singletonList(new StringChannel());
    }

}
public class StringChannel extends Channel<Integer, String> {

    @Override
    protected String doExecute(Integer o) {
        return "str" + o;
    }

    @Override
    public String getName() {
        return "String-Channel";
    }

    @Override
    public Collection<Component> getDownStrems() {
        return Collections.singletonList(new StringSink());
    }

}
public class StringSink extends Sink<String, Void>{

    @Override
    protected Void doExecute(String o) {
        return null;
    }

    @Override
    public String getName() {
        return "String-Sink";
    }

    @Override
    public Collection<Component> getDownStrems() {
        return null;
    }

}
/**
 *  流水線
 */
public class Pipeline {
    /**
     *  數據源
     */
    private Source source;

    public Pipeline(Source source) {
        this.source = source;
    }

    /**
     *  啟動
     */
    public void start() {
        source.execute(1);
    }
}

測試:

public class PipelineTest {

    @Test
    public void test() {
        Pipeline pipeline = new Pipeline(new IntegerSource());
        pipeline.start();
    }
}

執行結果:

Integer-Source receive 1 return 1

Incr-Channel receive 1 return 2

String-Channel receive 2 return str2

String-Sink receive str2 return null

 

事件驅動架構

淺談常用的架構模式

事件驅動模式

事件驅動是以某個具體事件為觸發條件,從而貫穿這個處理流程。通常事件驅動屬于發布訂閱模式或觀察者模式, 用于異步處理,解耦業務邏輯。具體實現有進程內的和分布式的方式,比如:EventBus, MQ等等。

 

代碼舉例:

public class OrderEventListener implements Listener<OrderEvent> {

    @Override
    public void onEvent(OrderEvent event) {
        System.out.println("receive event: " + event);
    }
}
public class EventBus {

    private final static List<Listener> listeners = new ArrayList<>();

    /**
     *  注冊監聽器
     * @param listener
     */
    public static void registerListener(Listener listener) {
        listeners.add(listener);
    }

    /**
     *  發布事件
     * @param event
     */
    public void publishEvent(Event event) {
        // 收到并處理事件
        listeners.forEach(l -> {
            l.onEvent(event);
        });
    }
}

測試:

public class EventBusTest {

    @Test
    public void publish() {
        OrderEvent event = new OrderEvent("order_2", OrderState.PENDING_PAYMENT);
        EventBus.registerListener(new OrderEventListener());
        EventBus eventBus = new EventBus();
        eventBus.publishEvent(event);
    }
}

Spring中也有事件發布和監聽(深入淺出Spring/SpringBoot 事件監聽機制):

@Component
public class OrderEventListener  {

    @Async
    @EventListener(OrderEvent.class)
    public void onEvent(OrderEvent event) {
        System.out.println("receive event: " + event);
    }
}
public class EventTest {
    @Autowired
    private ApplicationContext context;

    @Test
    public void publishEvent() {
        OrderEvent event = new OrderEvent("order_1", OrderState.PENDING_PAYMENT);
        context.publishEvent(event);
    }
}

 

總結

以上通過代碼實例簡單說明了工作中常用到的架構模式,但是模式不是固定的,工作中需結合實際情況按需使用即可。

分享到:
標簽:架構
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定