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. 抽象工厂:使对象的创建被实现在工厂接口所暴露出来的方法中;

  • 相关阅读:
    格式化数字,将字符串格式的数字,如:1000000 改为 1 000 000 这种展示方式
    jquery图片裁剪插件
    前端开发采坑之安卓和ios的兼容问题
    页面消息提示,上下滚动
    可以使用css的方式让input不能输入文字吗?
    智慧农村“三网合一”云平台测绘 大数据 农业 信息平台 应急
    三维虚拟城市平台测绘 大数据 规划 三维 信息平台 智慧城市
    农业大数据“一张图”平台测绘 大数据 房产 国土 农业 信息平台
    应急管理管理局安全生产预警平台应急管理系统不动产登记 测绘 大数据 规划 科教 三维 信息平台
    地下综合管廊管理平台测绘 大数据 地下管线 三维 信息平台
  • 原文地址:https://www.cnblogs.com/oxygenG/p/9797254.html
Copyright © 2011-2022 走看看