美文网首页
六大设计原则-单一职责原则

六大设计原则-单一职责原则

作者: 小杰66 | 来源:发表于2021-04-23 08:16 被阅读0次

    单一职责原则

    Single Responsibility Principle 简称SRP。

    什么是单一职责原则

    There should never be more than one reason for a class to change.
    就一个类而言,应该仅有一个引起它变化的原因。

    单一职责原则的好处

    一个类,只有一个引起它变化的原因。应该只有一个职责。每一个职责都是变化的一个轴线,如果一个类有一个以上的职责,这些职责就耦合在了一起。这会导致脆弱的设计。当一个职责发生变化时,可能会影响其它的职责。另外,多个职责耦合在一起,会影响复用性。例如:要实现逻辑和界面的分离。

    如何做到单一职责原则

    在一个类中如果有多个可能需要变化的东西,尽量保证只有一个可以变化,其他的变化就放在其他类中。

    我们可以按照下面的角色分类来划分职责:
    Information holder – 该对象设计为存储对象并提供对象信息给其它对象。
    Structurer – 该对象设计为维护对象和信息之间的关系
    Service provider – 该对象设计为处理工作并提供服务给其它对象
    Controller – 该对象设计为控制决策一系列负责的任务处理
    Coordinator – 该对象不做任何决策处理工作,只是delegate工作到其它对象上
    Interfacer – 该对象设计为在系统的各个部分转化信息(或请求)

    一定要做到单一职责原则吗

    单一职责原则是一个编写程序的标准,用职责或变化原因来衡量类设计的是否优良,但是职责和变化原因都是不可度量的,因项目而异,因环境而异。实际开发中违背单一职责原则是很正常的。

    代码举例

    • 改造前的代码,代码演示的是将商品添加到购物车,匿名函数中的职责非常的混乱。
    function Product(id, description) {
      this.getId = function () {
        return id;
      };
      this.getDescription = function () {
        return description;
      };
    }
    
    function Cart(eventAggregator) {
      var items = [];
    
      this.addItem = function (item) {
        items.push(item);
      };
    }
    
    (function () {
      var products = [
          new Product(1, "Star Wars Lego Ship"),
          new Product(2, "Barbie Doll"),
          new Product(3, "Remote Control Airplane"),
        ],
        cart = new Cart();
    
      function addToCart() {
        var productId = $(this).attr("id");
        var product = $.grep(products, function (x) {
          return x.getId() == productId;
        })[0];
        cart.addItem(product);
    
        var newItem = $("<li></li>")
          .html(product.getDescription())
          .attr("id-cart", product.getId())
          .appendTo("#cart");
      }
    
      products.forEach(function (product) {
        var newItem = $("<li></li>")
          .html(product.getDescription())
          .attr("id", product.getId())
          .dblclick(addToCart)
          .appendTo("#products");
      });
    })();
    
    
    • 改造后的代码
    // 事件聚合的功能
    // Event,用于Handler回调的代码
    // EventAggregator用来订阅和发布Event
    
    function Event(name) {
      var handlers = [];
    
      this.getName = function () {
        return name;
      };
    
      this.addHandler = function (handler) {
        handlers.push(handler);
      };
    
      this.removeHandler = function (handler) {
        for (var i = 0; i < handlers.length; i++) {
          if (handlers[i] == handler) {
            handlers.splice(i, 1);
            break;
          }
        }
      };
    
      this.fire = function (eventArgs) {
        handlers.forEach(function (h) {
          h(eventArgs);
        });
      };
    }
    
    function EventAggregator() {
      var events = [];
    
      function getEvent(eventName) {
        return $.grep(events, function (event) {
          return event.getName() === eventName;
        })[0];
      }
    
      this.publish = function (eventName, eventArgs) {
        var event = getEvent(eventName);
    
        if (!event) {
          event = new Event(eventName);
          events.push(event);
        }
        event.fire(eventArgs);
      };
    
      this.subscribe = function (eventName, handler) {
        var event = getEvent(eventName);
    
        if (!event) {
          event = new Event(eventName);
          events.push(event);
        }
    
        event.addHandler(handler);
      };
    }
    
    // Product类
    function Product(id, description) {
      this.getId = function () {
        return id;
      };
      this.getDescription = function () {
        return description;
      };
    }
    
    // Cart类,addItem方法负责触发itemAdded事件
    function Cart(eventAggregator) {
      var items = [];
    
      this.addItem = function (item) {
        items.push(item);
        eventAggregator.publish("itemAdded", item);
      };
    }
    
    // CartController类,接受cart对象和事件聚合器
    // 通过订阅itemAdded来增加li元素节点
    // 通过订阅productSelected事件来添加product。
    function CartController(cart, eventAggregator) {
      eventAggregator.subscribe("itemAdded", function (eventArgs) {
        var newItem = $("<li></li>")
          .html(eventArgs.getDescription())
          .attr("id-cart", eventArgs.getId())
          .appendTo("#cart");
      });
    
      eventAggregator.subscribe("productSelected", function (eventArgs) {
        cart.addItem(eventArgs.product);
      });
    }
    
    // Repository类用于获取数据,并暴露数据。
    function ProductRepository() {
      var products = [
        new Product(1, "Star Wars Lego Ship"),
        new Product(2, "Barbie Doll"),
        new Product(3, "Remote Control Airplane"),
      ];
    
      this.getProducts = function () {
        return products;
      };
    }
    
    // ProductController类
    // 根据数据生成产品列表,并通过交互事件触发productSelected事件
    function ProductController(eventAggregator, productRepository) {
      var products = productRepository.getProducts();
    
      function onProductSelected() {
        var productId = $(this).attr("id");
        var product = $.grep(products, function (x) {
          return x.getId() == productId;
        })[0];
        eventAggregator.publish("productSelected", {
          product: product,
        });
      }
    
      products.forEach(function (product) {
        var newItem = $("<li></li>")
          .html(product.getDescription())
          .attr("id", product.getId())
          .dblclick(onProductSelected)
          .appendTo("#products");
      });
    }
    
    (function () {
      var eventAggregator = new EventAggregator(),
        cart = new Cart(eventAggregator),
        cartController = new CartController(cart, eventAggregator),
        productRepository = new ProductRepository(),
        productController = new ProductController(
          eventAggregator,
          productRepository
        );
    })();
    
    

    相关文章

      网友评论

          本文标题:六大设计原则-单一职责原则

          本文链接:https://www.haomeiwen.com/subject/ykrolltx.html