美文网首页
设计模式总结干货2

设计模式总结干货2

作者: 高级java架构师 | 来源:发表于2018-09-19 16:26 被阅读8次

    如果想学习Java工程化、高性能及分布式、深入浅出。性能调优、Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级架构进阶群:180705916,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给大家

    另外还可以通过反射简洁生产过程,直接传入产品的类类型,生成对应的产品,示例如下:

    Java代码

    abstract class SMakeTea {  

        public abstract <T extends Tea> T 小猪带特效的奶茶制作工艺(Class<T> clz);  

    }  

    class SMe extends SMakeTea {  

        @Override  

        public <T extends Tea> T 小猪带特效的奶茶制作工艺(Class<T> clz) {  

            System.out.println("==============");  

            Tea tea = null;  

            try {  

                tea = (Tea) Class.forName(clz.getName()).newInstance();  

                tea.加奶();  

                tea.加茶();  

                tea.加料();  

                tea.打包();  

            } catch (Exception e) {  

                e.printStackTrace();  

            }  

            return (T) tea;  

        }  

    }  

    public class SStore {  

        public static void main(String[] args) {  

            SMe me = new SMe();  

            me.小猪带特效的奶茶制作工艺(ZhenZhuTea.class);  

            me.小猪带特效的奶茶制作工艺(YeGuoTea.class);  

        }  

    }

    六. 抽象工厂模式(Abstract Factory Pattern)

    代码示例

    Java代码

    //抽象产品类1  

    abstract class Drink {  

        public abstract void drink();  

    }  

    //抽象产品类2  

    abstract class Snack {  

        public abstract void snack();  

    }  

    //具体产品类们  

    class MilkTea extends Drink {  

        @Override public void drink() { System.out.println("一杯奶茶"); }  

    }  

    class Juice extends Drink {  

        @Override public void drink() { System.out.println("一杯果汁"); }  

    }  

    class HandGrab extends Snack {  

        @Override public void snack() { System.out.println("一个手抓饼"); }  

    }  

    class FishBall extends Snack {  

        @Override public void snack() { System.out.println("一碗鱼蛋"); }  

    }  

    //抽象工厂类  

    abstract class MakeFood {  

        abstract Drink createMakeDrink();  

        abstract Snack createMakeSnack();  

    }  

    //具体工厂类1  

    class FirstXiaoDi extends MakeFood {  

        @Override public Drink createMakeDrink() { return new MilkTea(); }  

        @Override public Snack createMakeSnack() { return new HandGrab(); }  

    }  

    //具体工厂类2  

    class SecondXiaoDi extends MakeFood {  

        @Override public Drink createMakeDrink() { return new Juice(); }  

        @Override public Snack createMakeSnack() { return new FishBall(); }  

    }  

    //客户端调用  

    public class Store {  

        public static void main(String[] args) {  

            //初始化两个小弟  

            MakeFood xiaodi1 = new FirstXiaoDi();  

            MakeFood xiaodi2 = new SecondXiaoDi();  

            for(int i = 0;i < 4 ;i++) {  

                System.out.println("====== 根据订单配餐: ======");  

                Drink drink = buyDrink() == 0 ?  

                    xiaodi1.createMakeDrink() : xiaodi2.createMakeDrink();  

                Snack snack = buySnack() == 0 ?   

                    xiaodi1.createMakeSnack() : xiaodi2.createMakeSnack();  

                drink.drink();  

                snack.snack();  

            }  

        }  

        /* 模拟用户点饮料,0代表要奶茶,1代表要果汁 */  

        private static int buyDrink() { return new Random().nextInt(2); }  

        /* 模拟用户点小吃,0代表要手抓饼,1代表要鱼蛋 */  

        private static int buySnack() { return new Random().nextInt(2); }  

    }

    输出结果

    两个名词(产品等级结构产品族)

    产品等级结构(继承)

    比如这里的抽象类是Drink(饮料),子类有奶茶,果汁,然后抽象饮料与具体饮料构成了一个产品等级结构,抽象饮料是父类,具体饮料是其子类。

    产品族

    同一工厂生产的,位于不同产品等级结构的一组产品,比如这里的奶茶和果汁属于饮料结构的一组产品,而手抓饼和鱼蛋则属于小吃结构的一组产品。

    四个角色与UML类图

    抽象工厂模式适用于创建的对象有多个相互关联或依赖的产品族;抽象工厂模式隔离具体类的生成,接口与实现分离,增加新的产品族很方便;但是扩展新的产品等级结构麻烦,需要修改抽象工厂,具体工厂类也要更改。

    七. 适配器模式(Adapter Pattern)

    两个彼此间没太大关联的类,想进行交互完成某些事情,不想直接去修改各自的接口,可以添加一个中间类,让他来协调两个类间的关系,完成相关业务,这种模式就叫适配器模式。

    然后分为:类适配器对象适配器两种,前者和适配者是继承关系,后者与适配者则是引用关系。

    对象适配器支持传入一个被适配器对象,因此可以做到对多种被适配接口进行适配。而类适配器直接继承无法动态修改,所以一般情况下对象适配器使用得更多!(Java不支持多重继承!!!)

    对象适配器例子(用得较多)

    Java代码

    /* 目标接口 */  

    interface Chinese {  

        void speakChinese(String string);  

    }  

    /* 需要适配的类 */  

    class English {  

        void speakEnglish(String string) { System.out.println("【英语】" + string); }  

    }  

    /* 适配器 */  

    class Translator implements Chinese{  

        private English english = new English();  

        Translator(English english) { this.english = english; }  

        @Override public void speakChinese(String string) { english.speakEnglish(string); }  

    }  

    /* 客户端调用 */  

    public class Client {  

        public static void main(String[] args) {  

            Chinese chinese = new Translator(new English());  

            chinese.speakChinese("那你很棒棒哦!");  

        }  

    输出结果

    类适配器例子

    Java代码

    /* 类适配器 */  

    class ClassTranslator extends English implements Chinese {  

        @Override public void speakChinese(String string) { speakEnglish(string); }  

    }  

    /* 客户端调用 */  

    public class ClientC {  

        public static void main(String[] args) {  

            ClassTranslator translator = new ClassTranslator();  

            translator.speakChinese("你也很好啊!");  

        }  

    输出结果

    除此之外还有个缺省适配器模式的名词,简单点说就是不需要实现接口中提供的所有方法时,先写一个抽象类实现这个接口,然后为每个方法提供一个默认实现(空方法),然后选择性覆盖某些方法实现需求,又称单接口适配器模式。

    八.装饰者模式(Decorator Pattern)

    动态的给对象添加一些额外的职责,就增加功能来说,装饰者模式比起生成子类更加灵活!就是想替代多重层继承的模式。其实就是一层套一层

    代码示例

    Java代码

    /* 抽象组件 */  

    abstract class Tea {  

        private String name = "茶";  

        public String getName() { return name; }  

        void setName(String name) { this.name = name; }  

        public abstract int price();  

    }  

    /* 具体组件 */  

    class MilkTea extends Tea {  

        MilkTea() { setName("奶茶"); }  

        @Override public int price() { return 5; }  

    }  

    class LemonTea extends Tea{  

        LemonTea() { setName("柠檬茶"); }  

        @Override public int price() { return 3; }  

    }  

    /* 抽象装饰类 */  

    abstract class Decorator extends Tea{  

        public abstract String getName();  

    }  

    /* 具体装饰类 */  

    class ZhenZhu extends Decorator {  

        Tea tea;  

        ZhenZhu(Tea tea) { this.tea = tea; }  

        @Override public String getName() { return "珍珠" + tea.getName(); }  

        @Override public int price() { return 2 + tea.price(); }  

    }  

    class YeGuo extends Decorator{  

        //...  

    }  

    class JinJu extends Decorator{  

        //...  

    }  

    class HongDou extends Decorator{  

        //...  

    }  

    /* 客户端调用 */  

    public class Store {  

        public static void main(String[] args) {  

            Tea tea1 = new MilkTea();  

            System.out.println("你点的是:" + tea1.getName() + " 价格为:" + tea1.price());  

            Tea tea2 = new LemonTea();  

            tea2 = new JinJu(tea2);  

            System.out.println("你点的是:" + tea2.getName() + " 价格为:" + tea2.price());  

            Tea tea3 = new MilkTea();  

            tea3 = new ZhenZhu(tea3);  

            tea3 = new YeGuo(tea3);  

            tea3 = new HongDou(tea3);  

            tea3 = new JinJu(tea3);  

            System.out.println("你点的是:" + tea3.getName() + " 价格为:" + tea3.price());  

        }  

    }

    输出结果

    九.组合模式(Composite Pattern)

    部分-整体模式,把具有相似的一组对象当做一个对象处理,用一种树状的结构组合对象,再提供统一的方法去访问相似的对象,以此忽略掉对象与对象容器间的差别。

    根节点枝结点叶子结点三个名词需要理解,类比上图,根节点是菜单,枝结点是饮料菜单和小吃菜单,叶子结点是奶茶,果汁,手抓饼和鱼蛋!

    代码示例

    Java代码

    /* 抽象组件 */  

    abstract class AbstractMenu {  

        public abstract void add(AbstractMenu menu);  

        public abstract AbstractMenu get(int index);  

        public abstract String getString();  

    }  

    /* 容器组件 */  

    class Menu extends AbstractMenu {  

        private String name;  

        private String desc;  

        private List<AbstractMenu> menus = new ArrayList<>();  

        Menu(String name, String desc) {  

            this.name = name;  

            this.desc = desc;  

        }  

        @Override public void add(AbstractMenu menu) { menus.add(menu); }  

        @Override public AbstractMenu get(int index) { return menus.get(index); }  

        @Override public String getString() {  

            StringBuilder sb = new StringBuilder("\n【菜单】:" + name + " 信息:" + desc + "\n");  

            for (AbstractMenu menu: menus) { sb.append(menu.getString()).append("\n"); }  

            return sb.toString();  

        }  

    }  

    /* 叶子组件 */  

    class MilkTea extends AbstractMenu {  

        private String name;  

        private String desc;  

        private int price;  

        MilkTea(String name, String desc, int price) {  

            this.name = name;  

            this.desc = desc;  

            this.price = price;  

        }  

        @Override public void add(AbstractMenu menu) { /*未使用*/ }  

        @Override public AbstractMenu get(int index) { return null; }  

        @Override public String getString() {  

            return " - 【奶茶】* " + name + " 标注:" + desc + " 价格:" + price;  

        }  

    }  

    class MilkTea extends AbstractMenu {  

        //...  

    }  

    class HandCake  extends AbstractMenu {  

        //...  

    }  

    class FishBall  extends AbstractMenu {  

        //...  

    }  

    /* 客户端调用 */  

    public class Store {  

        public static void main(String[] args) {  

            AbstractMenu mainMenu = new Menu("大菜单", "包含所有子菜单");  

            AbstractMenu drinkMenu = new Menu("饮品菜单", "都是喝的");  

            AbstractMenu eatMenu = new Menu("小吃菜单", "都是吃的");  

            AbstractMenu milkTea = new MilkTea("珍珠奶茶", "奶茶+珍珠", 5);  

            AbstractMenu juice = new Juice("鲜榨猕猴桃枝", "无添加即榨", 8);  

            AbstractMenu ball = new FishBall("咖喱鱼蛋", "微辣", 6);  

            AbstractMenu cake = new HandCake("培根手抓饼", "正宗台湾风味", 8);  

            drinkMenu.add(milkTea);  

            drinkMenu.add(juice);  

            eatMenu.add(ball);  

            eatMenu.add(cake);  

            mainMenu.add(drinkMenu);  

            mainMenu.add(eatMenu);  

            System.out.println(mainMenu.getString());  

        }  

    }

    输出结果

    十.桥接模式(Bridge Pattern)

    基于单一职责原则,如果系统中的类存在多个变化的维度,通过该模式可以将这几个维度分离出来, 然后进行独立扩展。这些分离开来的维度,通过在抽象层持有其他维度的引用来进行关联,就好像在两个维度间搭了桥一样,所以叫桥接模式。

    代码示例(变化的三个维度:配餐,扒类)

    Java代码

    /* 抽象部分 */  

    abstract class Rations {  

        abstract String rations();  

    }  

    /* 扩展抽象部分 */  

    class Rice extends Rations {  

        @Override public String rations() { return "饭"; }  

    }  

    class Spaghetti extends Rations {  

        @Override public String rations() { return "意粉"; }  

    }  

    /* 实现部分 */  

    abstract class Steak {  

        Rations rations;  

        Steak(Rations rations) { this.rations = rations; }  

        abstract String sale();  

    }  

    /* 具体实现部分 */  

    class BeefSteak extends Steak{  

        BeefSteak(Rations rations) { super(rations); }  

        @Override public String sale() { return "牛扒"+ (rations == null ? "" : rations.rations()); }  

    }  

    class PorkSteak extends Steak {  

        PorkSteak(Rations rations) { super(rations); }  

        @Override public String sale() { return "猪扒"+ (rations == null ? "" : rations.rations()); }  

    }  

    /* 客户端调用 */  

    public class Restaurant {  

        public static void main(String[] args) {  

            System.out.println("\n" + new Date(System.currentTimeMillis()));  

            System.out.println("==================");  

            Steak steak1 = new BeefSteak(new Rice());  

            System.out.println("卖出了一份:" + steak1.sale());  

            Steak steak2 = new PorkSteak(new Spaghetti());  

            System.out.println("卖出了一份:" + steak2.sale());  

            Steak steak3 = new PorkSteak(null);  

            System.out.println("卖出了一份:" + steak3.sale());  

             System.out.println("==================");  

    输出结果

    十一.外观模式(Facade Pattern)

    要求一个子系统的外部与内部的通信必须通过一个统一的对象进行,外观模式提供一个高层次的接口,使得子系统更易于使用。(其实就是封装,用于解决类与类间的依赖关系,比如本来是:玩家依赖于:Q,A,E,R等键位对象,现在变成只依赖与脚本对象从而降低了类间的耦合度。)

    代码示例

    Java代码

    /* 子系统 */  

    class A {  

        String a() { return "A"; }  

    }  

    class Q { /* ... */ }  

    class Space { /* ... */ }  

    class LeftClick { /* ... */ }  

    /* 外观类 */  

    class JiaoBen {  

        A a;  

        Q q;  

        LeftClick leftClick;  

        Space space;  

        JiaoBen() {  

            a = new A();  

            leftClick = new LeftClick();  

            q = new Q();  

            space = new Space();  

        }  

        String 锐雯() {  

            StringBuilder sb = new StringBuilder();  

            sb.append(q.q()).append(" + ");  

            sb.append(space.space()).append(" + ");  

            sb.append(a.a()).append(" + ");  

            sb.append(leftClick.leftClick()).append(" + ");  

            sb.append(q.q()).append(" + ");  

            sb.append(space.space()).append(" + ");  

            sb.append(a.a()).append(" + ");  

            sb.append(leftClick.leftClick()).append(" + ");  

            sb.append(q.q()).append(" + ");  

            sb.append(space.space()).append(" + ");  

            sb.append(a.a()).append(" + ");  

            sb.append(leftClick.leftClick()).append("\n");  

            return sb.toString();  

        }  

    }  

    /* 客户端调用 */  

    public class XLoLer {  

        public static void main(String[] args) {  

            JiaoBen jiaoBen = new JiaoBen();  

            System.out.println("=== 锐雯一键光速QA ===\n" + jiaoBen.锐雯());  

        }  

    }

    输出结果

    十二. 享元模式(Flyweight Pattern)

    当存在多个相同对象时,可以使用享元模式减少相同对象创建引起的内存消耗,提高程序性能。说到共享,还分内部状态与外部状态

    内部状态固定不变可共享的的部分,存储在享元对象内部,比如例子中的花色

    外部状态可变不可共享的部分,一般由客户端传入享元对象内部,比如例子里的大小

    示例代码

    Java代码

    /* 抽象对象的父类 */  

    abstract class Card {  

        abstract void showCard(String num);  //传入外部状态参数,大小  

    }  

    /* 具体享元对象 */  

    public class SpadeCard extends Card{  

        public SpadeCard() { super(); }  

        @Override public void showCard(String num) { System.out.println("黑桃:" + num); }  

    }  

    public class HeartCard extends Card { /* ... */ }  

    public class ClubCard extends Card { /* ... */ }  

    public class DiamondCard extends Card { /* ... */ }  

    /* 享元工厂 */  

    public class PokerFactory {  

        static final int Spade = 0;  //黑桃  

        static final int Heart  = 1; //红桃  

        static final int Club  = 2; //梅花  

        static final int Diamond  = 3;   //方块  

        public static Map<Integer, Card> pokers = new HashMap<>();  

        public static Card getPoker(int color) {  

            if (pokers.containsKey(color)) {  

                System.out.print("对象已存在,对象复用...");  

                return pokers.get(color);  

            } else {  

                System.out.print("对象不存在,新建对象...");  

                Card card;  

                switch (color) {  

                    case Spade: card = new SpadeCard(); break;  

                    case Heart: card = new HeartCard(); break;  

                    case Club: card = new ClubCard(); break;  

                    case Diamond: card = new DiamondCard(); break;  

                    default: card = new SpadeCard(); break;  

                }  

                pokers.put(color,card);  

                return card;  

            }  

        }  

    /* 客户端调用 */  

    public class Player {  

        public static void main(String[] args) {  

            for (int k = 0; k < 10; k ++){  

                Card card = null;  

                //随机花色  

                switch ((int)(Math.random()*4)) {  

                    case 0: card = PokerFactory.getPoker(PokerFactory.Spade); break;  

                    case 1: card = PokerFactory.getPoker(PokerFactory.Heart); break;  

                    case 2: card = PokerFactory.getPoker(PokerFactory.Club); break;  

                    case 3: card = PokerFactory.getPoker(PokerFactory.Diamond); break;  

                }  

                if(card != null) {  

                    //随机大小  

                    int num = (int)(Math.random()*13 + 1);  

                    switch (num) {  

                        case 11: card.showCard("J"); break;  

                        case 12: card.showCard("Q"); break;  

                        case 13: card.showCard("K"); break;  

                        default: card.showCard(num+""); break;  

                    }  

                }  

            }  

        }  

    输出结果

    未完待续。。。

    相关文章

      网友评论

          本文标题:设计模式总结干货2

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