zoukankan      html  css  js  c++  java
  • 设计模式之六大原则

     1. 开闭原则

     开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简单来说:就是为了使程序的扩展性好,易于维护和升级

     2. 接口隔离原则

     使用多个隔离的接口,优于使用单个接口,降低类之间的耦合度,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。在开发过程当中回尽量地去降低依赖,降低耦合

     3. 迪米特法则

     一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立

     4. 单一职责原则

     单一职责的定义:应该有且只有一个原因引起类的变更。换句话说就是一个接口只做一件事,即一个职责一个接口。

     但是困难的是划分职责时并没有一个标准,最终都是需要从实际的项目去考虑。我们在设计的时候,尽量单一,然后对于其实现类就要多方面的考虑。不能死套单一职责原则,否则会增加很多类,给维护带来不便

     5. 里氏代换原则

     任何基类可以出现的地方,子类一定可以出现。LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。

     里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范、

     6. 依赖倒转原则

     这个是开闭原则的基础,具体内容:真对接口编程,依赖于抽象而不依赖于具体

     java中抽象指接口或抽象类,两者都不能直接被实例化的;细节就是实现类,实现接口或者集成抽象类而产生的也就细节,也就是可以可以加上一个关键字new产生的对象。高层模块就是调用端,低层模块就是具体实现类。

     依赖倒置原则在java中表现就是,模块间依赖通过抽象发生,实现类之间不发生直接依赖关系,其依赖关系是通过接口或者抽象类产生的。

     如果类与类直接依赖细节,那么就会直接耦合。如此一来当修改时,就会同时修改依赖者代码,这样限制了可拓展性

     设计模式分为三大类:

     创建型模式:工厂方法模式抽象工厂模式、单例模式、建造者模式、原型模式;

     结构型模式:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式;

     行为型模式:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式;

    简单工厂

    首先要明确的是,简单工厂模式不属于23种设计模式,它引入了创建者的概念,将实例化的代码从应用代码中抽离,在工厂类的静态方法中只处理被创建的对象,如果业

    务需要变更则需要在工厂类中添加具体的实现类,因此维护性较差。以"工厂创建咖啡"为例说明,如下:

    1. 物品标识类Coffee和已有的类

    package com.oxygen.bean;
    
    /**
     * 
     * 咖啡则作为一种抽象概念:拿铁、美式咖啡、卡布奇诺等均为咖啡家族的一种产品
     * @author Oxygen
     *
     */
    public abstract class Coffee {
    
        public abstract String desc(); //获取coffee名称
    
    }
    
    class Americano extends Coffee { // 美式咖啡
    
        @Override
        public String desc() {
            return "美式咖啡";
        }
    
    }
    
    class Cappuccino extends Coffee { //卡布奇诺
    
        @Override
        public String desc() {
            return "卡布奇诺";
        }
    
    }
    
    class Latte extends Coffee { //拿铁
    
        @Override
        public String desc() {
            return "拿铁";
        }
    
    }

    View Code

    2. 简单工厂

    package com.oxygen.bean;
    
    /**
     * 创建材料的工厂类
     * @author Oxygen 
     *    @date 2018年10月16日
     */
    public class SimpleFactory {
        /**
         * 
         * @param type 材料类型
         * @return
         */
        public static Coffee createInstance(String type) {
            if ("Americano".equals(type)) {
                return new Americano();
            } else if ("Cappuccino".equals(type)) {
                return new Cappuccino();
            } else if ("Latte".equals(type)) {
                return new Latte();
            } else {
                throw new RuntimeException("type[" + type + "]类型不可识别,没有匹配到可实例化的对象!");
            }
        }
    
        public static void main(String[] args) {
            System.out.println(SimpleFactory.createInstance("Americano").desc());
            System.out.println(SimpleFactory.createInstance("Cappuccino").desc());
            System.out.println(SimpleFactory.createInstance("Latte").desc());
        }
    }

    View Code

    3. 输出结果

     

    美式咖啡
    卡布奇诺
    拿铁

    工厂方法

     工厂方法模式其定义了一个创建对象的接口,由子类决定要实例化的类是哪一个,工厂方法让类把实例化推迟到了子类,也就是说一个工厂只能生成特定的Coffee

    1. 工厂类

    package com.oxygen.bean;
    
    /**
     * Coffee工厂
     * @author Oxygen 
     *    @date 2018年10月16日
     */
    public abstract interface CoffeeFactory {
        public abstract Coffee[] createCoffee();
    
        public static void main(String[] args) {
            CoffeeFactory chinaCoffeeFactory = new ChinaCoffeeFactory();
            Coffee[] chinaCoffees = chinaCoffeeFactory.createCoffee();
            System.out.print("中国咖啡工厂可以生产的咖啡有:");
            print(chinaCoffees);
            CoffeeFactory americaCoffeeFactory = new AmericaCoffeeFactory();
            Coffee[] americaCoffees = americaCoffeeFactory.createCoffee();
            System.out.print("美国咖啡工厂可以生产的咖啡有:");
            print(americaCoffees);
        }
    
        public static void print(Coffee[] c) {
            for (Coffee coffee : c) {
                System.out.print(coffee.desc() + " ");
            }
            System.out.println();
        }
    }
    
    class ChinaCoffeeFactory implements CoffeeFactory { //中国咖啡工厂
    
        @Override
        public Coffee[] createCoffee() {
            return new Coffee[] { new Cappuccino(), new Latte() };
        }
    
    }
    
    class AmericaCoffeeFactory implements CoffeeFactory { //美国咖啡工厂
    
        @Override
        public Coffee[] createCoffee() {
            return new Coffee[] { new Americano(), new Latte() };
        }
    
    }

    View Code

    2. 输出结果

     

    中国咖啡工厂可以生产的咖啡有:卡布奇诺 拿铁 
    美国咖啡工厂可以生产的咖啡有:美式咖啡 拿铁 

    抽象工厂

    提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类,在上述的场景上继续延伸:咖啡工厂做大做强,引入了新的饮品种类:茶、 碳酸饮

    料。中国工厂只能制造咖啡和茶,美国工厂只能制造咖啡和碳酸饮料,如果继续使用上述工厂方法方式,除去对应的产品实体类还需要新增2个抽象工厂(茶制造

    工厂、碳酸饮料制造工厂),4个具体工厂实现。

    随着产品的增多,会导致类爆炸,这显然是不能接受的。所以这里引出一个概念产品家族,在此例子中,不同的饮品就组成我们的饮品家族, 饮品家族开始承担

    创建者的责任,负责制造不同的产品。如下:

    package com.oxygen.bean;
    
    public interface AbstractDrinksFactory {
    
        Coffee createCoffee(); //制造咖啡
    
        Tea createTea(); //制造茶
    
        Sodas createSodas();//制造碳酸饮料
    }
    
    /**
     * 中国饮品工厂:制造咖啡与茶
     */
    class ChinaDrinksFactory implements AbstractDrinksFactory {
    
        @Override
        public Coffee createCoffee() {
            return new Latte();
        }
    
        @Override
        public Tea createTea() {
            return new MilkTea();
        }
    
        @Override
        public Sodas createSodas() {
            // TODO Auto-generated method stub
            return null;
        }
    }
    
    /**
     * 美国饮品制造工厂:制造咖啡和碳酸饮料
     */
    class AmericaDrinksFactory implements AbstractDrinksFactory {
    
        @Override
        public Coffee createCoffee() {
            // TODO Auto-generated method stub
            return new Latte();
        }
    
        @Override
        public Tea createTea() {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public Sodas createSodas() {
            // TODO Auto-generated method stub
            return new CocaCola();
        }
    
    }

    View Code

    总结

    工厂模式可以帮助我们针对抽象接口编程,而不是针对具体类编程,在不同的场景下按具体情况来

    1. 简单工厂:不能算是真正意义上的设计模式,但可以将客户程序从具体类解耦;

    2. 工厂方法:使用继承,把对象的创建委托给子类,由子类来实现创建方法,可以看作是抽象工厂模式中只有单一产品的情况;

    3. 抽象工厂:使对象的创建被实现在工厂接口所暴露出来的方法中;

  • 相关阅读:
    非网管交换机和网管交换机的区别
    百兆工业交换机与千兆工业交换机如何计算码率?
    光纤收发器的测试内容介绍
    使用expect在script中切换到root用户(精华)
    彻底解决ssh.invoke_shell() 返回的中文问题
    Python3之paramiko模块
    linux expect详解
    Apache HTTP Server 虚拟主机配置
    Apache 配置详解
    apache 基本配置
  • 原文地址:https://www.cnblogs.com/oxygenG/p/9797254.html
Copyright © 2011-2022 走看看