设计模式之小金的泡妞学(上)

    在程序员的世界里,泡妞可真的是一门很大的学问,因为程序员天真单纯腼腆,不懂得套路,嘴巴也不会说,每天都沉浸和陶醉在代码的世界里,不亦乐乎,对于泡妞来说,基本上不怎么会,更不要说屌丝逆袭了,所以跟大家从设计模式的角度分享一下身边一位高人的泡妞绝学,开启小金同学的泡妞之路:

【相遇之观察者模式】

     在一个阳光明媚的清晨,桃花那个朵朵开,小金同学走过一座小桥边,遇到了一位弹琴的姑娘,真可谓是暖阳下,我迎芬芳,是谁家的姑娘,我走在了那座小桥上,你抚琴奏忧伤,桥边歌唱的小姑娘 你眼角在流淌,她有着长长的乌黑发,一双眼明亮,风华模样,你落落大方,姑娘你让我心荡漾,小鹿在乱撞呀。如此美人,怎能让小金一人欣赏,所以很多小哥哥,也都注意到了琴声优美的姑娘,姑娘观察到这么多人在关注她,这琴弹奏的越来越美了。后续故事暂且放一放,这里首先跟大家介绍第一个设计模式,观察者模式,上面的场景中,就用到了我们的观察者模式,弹琴的姑娘是被观察者,也是观察者模式中的主题角色,小金和其他的小哥哥就是观察者,美女弹琴,琴声悠扬,主题做出相应的操作,观察者通过眼睛和耳朵都能收到通知。

观察者模式定义:

     【观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态上发生改变的时候,会通知所有的观察者对象,让他们能够自动去更新自己】

观察者模式角色:

     【抽象主题角色】:把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类或接口来实现。

     【抽象观察者角色】:为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。

     【具体主题角色】:在具体主题内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个子类实现。

     【具体观察者角色】:该角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。通常用一个子类实现。

观察者模式类图:

场景之代码实现:

定义抽象主题角色:

package com.harderxin.pattern.observer;

/**
 * @author 吴鑫
 * @contact [email protected]
 * @date 2019/12/11 10:42
 * @description 定义抽象主题角色
 */
public interface Observed {

    /**
     * 添加观察者
     *
     * @param watcher
     */
    void addWathcer(Watcher watcher);

    /**
     * 删除观察者
     *
     * @param watcher
     */
    void removeWatcher(Watcher watcher);

    /**
     * 通知观察者
     *
     * @param action
     */
    void notifyWatchers(String action);
}

定义抽象观察者角色:

package com.harderxin.pattern.observer;

/**
 * @author 吴鑫
 * @contact [email protected]
 * @date 2019/12/11 10:42
 * @description 定义抽象观察者角色
 */
public interface Watcher {

    /**
     * 观察者收到通知后做出相应操作
     *
     * @param action
     */
    void update(String action);
}

定义具体的主题角色:

package com.harderxin.pattern.observer;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 吴鑫
 * @contact [email protected]
 * @date 2019/12/11 10:55
 * @description 定义一个具体的主题角色,场景中弹琴的女孩
 */
public class Girl implements Observed {

    // 一个具体的主题角色有很多观察者
    List<Watcher> watchers = new ArrayList<>();

    @Override
    public void addWathcer(Watcher watcher) {
        watchers.add(watcher);
    }

    @Override
    public void removeWatcher(Watcher watcher) {
        watchers.remove(watcher);
    }

    @Override
    public void notifyWatchers(String action) {
        for (Watcher watcher : watchers) {
            watcher.update(action);
        }
    }
}

定义具体的观察者角色:

package com.harderxin.pattern.observer;

/**
 * @author 吴鑫
 * @contact [email protected]
 * @date 2019/12/11 10:58
 * @description 定义一个具体的观察者角色
 */
public class Boy implements Watcher {

    private String name;

    public Boy(String name) {
        this.name = name;
    }

    /**
     * 主题发出通知信息,观察者可接收到
     *
     * @param action
     */
    @Override
    public void update(String action) {
        System.out.println(this.name + " 接收到来自美女的通知:" + action);
    }
}

测试类:

package com.harderxin.pattern.observer;

/**
 * @author 吴鑫
 * @contact [email protected]
 * @date 2019/12/11 11:00
 * @description 观察者模式:启动类
 */
public class Main {

    public static void main(String[] args) {
        // 定义一个主题角色:桥边弹琴的姑娘
        Observed girl = new Girl();

        // 定义多个观察者角色:小金和很多小哥哥
        Watcher boyOne = new Boy("小金");
        Watcher boyTwo = new Boy("小华");
        Watcher boyThree = new Boy("小鹏");
        Watcher boyFour = new Boy("小鑫");

        // 小金和小哥哥观察美女弹琴
        girl.addWathcer(boyOne);
        girl.addWathcer(boyTwo);
        girl.addWathcer(boyThree);
        girl.addWathcer(boyFour);

        // 姑娘弹琴,看到有这么多小哥哥,跟他们打招呼
        girl.notifyWatchers("小哥哥们好");

        // 小鑫因为要忙着加班,先走一步了,姑娘少了一个观察者
        girl.removeWatcher(boyFour);
    }
}

【问联系方式之策略模式】

     如此美丽的姑娘,小金看的两眼冒金星,心跳砰砰加速,这就是一见钟情的感觉呀,小金的脑袋里就在想怎么能够要到姑娘的微信,于是乎大脑开始对话了:
       左脑:你可以直接上去要微信,可是你有这个胆子么?
       右脑:他没这个胆子,还是让朋友帮忙问问吧
       左脑:可以制造相遇的机会,或者说打听路线之类的
       右脑:那都是老套路了,能不能来点新鲜的,比如英雄救美呀
       左脑:啊呸,你的更俗
        ..................

     经过左右大脑的一番激烈的斗争,小金同学一脸茫然
     好了,在这里,又一个设计模式要诞生了,就是策略模式,问联系方式是需要讲究策略的,好的策略才不会觉得尴尬。

策略模式定义:

   【策略模式,又叫算法簇模式,就是定义了不同的算法族,并且之间可以互相替换,此模式让算法的变化独立于使用算法的客户,你可以动态的改变对象的行为】说白了就是策略模式有很多种可选方案,然后你可以在规定的场景中随意选择对应的方案,达到想要的效果。

策略模式角色:

     环境对象:该类中实现了对抽象策略中定义的接口或者抽象类的引用。
     抽象策略对象:它可由接口或抽象类来实现。
      具体策略对象:它封装了实现同不功能的不同算法。

策略模式类图:

场景之代码实现:

定义抽象策略对象:

package com.harderxin.pattern.strategy;

/**
 * @author 吴鑫
 * @contact [email protected]
 * @date 2019/12/11 11:31
 * @description 定义抽象策略对象:泡妞策略
 */
public interface ChaseGirlStrategy {

    /**
     * 获取联系方式
     *
     * @return
     */
    String getContractWay();

}

定义具体策略对象:

package com.harderxin.pattern.strategy;

/**
 * @author 吴鑫
 * @contact [email protected]
 * @date 2019/12/11 11:45
 * @description 定义具体策略对象:直接上去问
 */
public class OpenStrategy implements ChaseGirlStrategy {

    @Override
    public String getContractWay() {
        return "直接上去问联系方式";
    }
}
package com.harderxin.pattern.strategy;

/**
 * @author 吴鑫
 * @contact [email protected]
 * @date 2019/12/11 11:46
 * @description 定义具体策略对象:英雄救美
 */
public class HeroStrategy implements ChaseGirlStrategy {

    @Override
    public String getContractWay() {
        return "英雄救美,然后问联系方式";
    }
}
package com.harderxin.pattern.strategy;

/**
 * @author 吴鑫
 * @contact [email protected]
 * @date 2019/12/11 11:47
 * @description 定义具体策略对象:请朋友帮忙
 */
public class FriendStragegy implements ChaseGirlStrategy {

    @Override
    public String getContractWay() {
        return "请朋友帮忙,通过朋友获取联系方式";
    }
}

定义环境对象:

package com.harderxin.pattern.strategy;

/**
 * @author 吴鑫
 * @contact [email protected]
 * @date 2019/12/11 11:50
 * @description 定义一个环境对象:只要遇到了喜欢的女孩,随时都是泡妞环境吖
 */
public class ChaseGirlEnviroment {

    // 持有泡妞策略的引用
    private ChaseGirlStrategy strategy;

    public void setStrategy(ChaseGirlStrategy strategy) {
        this.strategy = strategy;
    }

    public String getContractWay() {
        return strategy.getContractWay();
    }
}

测试类:

package com.harderxin.pattern.strategy;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;

/**
 * @author 吴鑫
 * @contact [email protected]
 * @date 2019/12/11 11:30
 * @description 策略模式:启动类
 */
public class Main {

    public static void main(String[] args) {
        // 定义一个泡妞的环境对象:场景中的小桥边
        ChaseGirlEnviroment enviroment = new ChaseGirlEnviroment();

        // 左脑说:直接上去问微信
        ChaseGirlStrategy srategy = new OpenStrategy();
        // 将这个策略运用到场景中
        enviroment.setStrategy(srategy);
        System.out.println(enviroment.getContractWay());

        // 右脑说:英雄救美吧
        srategy = new HeroStrategy();
        // 将这个策略运用到场景中
        enviroment.setStrategy(srategy);
        System.out.println(enviroment.getContractWay());

    }
}

最后小金还是靠自己的才华,在现场厚着脸皮唱了一首情歌《桥边姑娘》拿到了联系方式,那个激动和开心溢于言表。

【约会之装饰模式】

     拿到了妹子的联系方式,小金也把策略模式运用到了如何聊天、如何调动妹子情绪、如何展现自己的才华等方面,自古套路得人心啊,经过一段时间的联系,软磨硬泡,妹子终于答应跟小金约会了,地点选在了一家茶餐厅,小金早早的就来约定的地点等候了,并且为了体现自己是个暖男,给妹子点了一杯白开水,然后准备了茶叶包、红糖包、咖啡包,想让妹子根据自己的心情和爱好选择自己喜欢喝的,这就是细节,说不定妹子就被这些小细节感动了呢,妹子如约而至,今天打扮很漂亮,长长的散发,白白的裙子,让小金同学看了春心那个荡漾呀,服务员端上了一杯白开水,让妹子自己天添加喜欢的饮品,妹子会选择哪个呢?好了,有一个设计模式要横空出世了,这就是装饰者模式,这个场景中白开水是具体的构建角色,茶叶、糖、咖啡是装饰角色,用来装饰水,也就是装饰具体的构建角色,那么在装饰模式中又有哪些角色参与呢?

装饰模式定义:

     【装饰模式是在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象,又叫做包装模式。装饰模式可以在不创造更多子类的情况下,将对象的功能加以扩展,是继承关系的一个替代方案】

装饰模式角色:

     抽象构件角色(Component):给出一个抽象接口,以规范准备接收附加责任的对象。

     具体构件角色(Concrete Component):定义一个将要接收附加责任的类

     装饰角色(Decorator):持有一个构件(Component)对象的引用,并定义一个与抽象构件接口一致的接口

     具体装饰角色(Concrete Decorator):负责给构件对象贴上附加的责任

装饰模式类图:

场景之代码实现:

定义抽象构建角色:

package com.harderxin.pattern.decorator;

/**
 * @author 吴鑫
 * @contact [email protected]
 * @date 2019/12/12 11:13
 * @description 定义抽象构建角色
 */
public interface WaterComponent {

    /**
     * 提供一个喝的方法
     */
    void drink();
}

定义具体构建角色,无论如何这个是基础服务:

package com.harderxin.pattern.decorator;

/**
 * @author 吴鑫
 * @contact [email protected]
 * @date 2019/12/12 11:24
 * @description 定义具体构建角色
 */
public class ConcreteWaterComponent implements WaterComponent {
    @Override
    public void drink() {
        System.out.println("喝水");
    }
}

定义抽象装饰角色,持有抽象构建角色引用:

package com.harderxin.pattern.decorator;

/**
 * @author 吴鑫
 * @contact [email protected]
 * @date 2019/12/12 11:25
 * @description 定义装饰角色:水的装饰
 */
public abstract class WaterAbstractDecorator implements WaterComponent {

    // 持有构建对象的引用
    private WaterComponent waterComponent;

    /**
     * 通过构造方法传递给被装饰者
     *
     * @param waterComponent
     */
    public WaterAbstractDecorator(WaterComponent waterComponent) {
        this.waterComponent = waterComponent;
    }

    @Override
    public void drink() {
        if (null != waterComponent) {
            waterComponent.drink();
        }
    }
}

定义具体装饰角色:

package com.harderxin.pattern.decorator;

/**
 * @author 吴鑫
 * @contact [email protected]
 * @date 2019/12/12 11:30
 * @description 定义具体装饰者角色
 */
public class TeaDecorator extends WaterAbstractDecorator {

    public TeaDecorator(WaterComponent waterComponent) {
        super(waterComponent);
    }

    /**
     * 定义装饰的行为
     */
    public void addToDrink() {
        System.out.println("加点茶叶");
    }

    @Override
    public void drink() {
        addToDrink();
        super.drink();
    }
}
package com.harderxin.pattern.decorator;

/**
 * @author 吴鑫
 * @contact [email protected]
 * @date 2019/12/12 11:30
 * @description 定义具体装饰者角色
 */
public class SugarDecorator extends WaterAbstractDecorator {

    public SugarDecorator(WaterComponent waterComponent) {
        super(waterComponent);
    }

    /**
     * 定义装饰的行为
     */
    public void addToDrink() {
        System.out.println("加点糖");
    }

    @Override
    public void drink() {
        addToDrink();
        super.drink();
    }
}
package com.harderxin.pattern.decorator;

/**
 * @author 吴鑫
 * @contact [email protected]
 * @date 2019/12/12 11:30
 * @description 定义具体装饰者角色
 */
public class CoffeeDecorator extends WaterAbstractDecorator {

    public CoffeeDecorator(WaterComponent waterComponent) {
        super(waterComponent);
    }

    /**
     * 定义装饰的行为
     */
    public void addToDrink() {
        System.out.println("加点咖啡");
    }

    @Override
    public void drink() {
        addToDrink();
        super.drink();
    }
}

测试类:

package com.harderxin.pattern.decorator;

/**
 * @author 吴鑫
 * @contact [email protected]
 * @date 2019/12/12 11:08
 * @description 装饰者模式:启动类
 */
public class Main {

    public static void main(String[] args) {

        WaterComponent component = new ConcreteWaterComponent();

        // 喝白开水太枯燥了,来随机装饰一下吧
        // 加点茶叶
        component = new TeaDecorator(component);
        // 加点咖啡
        component = new CoffeeDecorator(component);
        // 加点糖
        component = new SugarDecorator(component);

        component.drink();

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

        // 下面的写法是不是似曾相识
        WaterComponent component2 = new SugarDecorator(new CoffeeDecorator(new TeaDecorator(new ConcreteWaterComponent())));
        component2.drink();
    }
}

     小金和妹子聊得很好,上到天文地理,下到语数外、文物历史、计算机绝学,这把他能的,一下午的聊天过程中,妹子是喝了茶、喝了加糖的咖啡,两人相谈盛欢,空气中弥漫着爱情的味道。

发布了241 篇原创文章 · 获赞 305 · 访问量 54万+

猜你喜欢

转载自blog.csdn.net/HarderXin/article/details/103508566
今日推荐