23种设计模式趣谈

0 阅读注意事项

里面的趣谈故事部分为套用名著人物的虚构故事。
选用四大名著角色和故事的原因:
一是这些都是耳熟能详的角色,希望能在读者脑海里勾出点想象;
二是为了读者能更好的记住这些小故事,从而帮助理解这23种设计模式。

不过,故事只是一种让我们记住这些知识的途径,但是体会理解是否正确还是要回归正经的概念。可见此博文:
23种设计模式解析

1 工厂方法模式(Factory Method)

1.1 普通工厂模式

士兵的种类有步兵和骑兵。
刘备手下有五千步兵,一千骑兵,都存放在练兵场。
谁想领兵,得向练兵场负责人递纸条,领步兵的话得写”Infantry“,领骑兵的话得写”Trooper“。

public interface Soldier{
    void fight();
}

public class Infantry implements Soldier{
    @Override
    public void fight() {
        System.out.println("Infantry walk forward!");
    }
}
public class Trooper implements Soldier{

    @Override
    public void fight() {
        System.out.println("Trooper horse riding!");
    }
}
public class Principal{

    public Soldier produce(String type) {
        if ("Infantry".equals(type)) {
            return new Infantry();
        } else if ("Trooper".equals(type)) {
            return new Trooper();
        } else {
            System.out.println("请输入正确的类型!");
            return null;
        }
    }
}
public class Test {
    public static void main(String[] args) {
        Principal principal= new Principal();
        Soldier infantry= principal.produce("Infantry");
        Soldier trooper= principal.produce("Trooper");
        infantry.fight();
        trooper.fight();
    }
}
  • ?但是却产生了一个问题,张飞常常忘了Infantry和Trooper怎么拼写,怎么着都领不出兵。

  • 诸葛锦囊:我们可以用虎符啊!

1.2 多个工厂方法模式

于是练兵场负责人连日研发出了两种虎符,一种刻着Infantry,持有可调用步兵,一种刻着Trooper,持有可调用骑兵。
这下张飞摆脱了拼写Infantry和Trooper的烦恼,效率大幅度提升。

public class Principal{

    public Soldier produceInfantry() {
        return new Infantry();
    }
    public Soldier produceTrooper() {
        return new Trooper();
    }
}
public class Test {
    public static void main(String[] args) {
        Principal principal= new Principal();
        Soldier infantry= principal.produceInfantry();
        Soldier trooper= principal.produceTrooper();
        infantry.fight();
        trooper.fight();
    }
}
  • ?但是时间久了,一个问题浮出水面,战事24小时都在发生,但是练兵场负责人却没有时时都在上班。

  • 诸葛锦囊:可以让持虎符者即可领兵!

1.3 静态工厂方法模式

练兵场出了新规,凡是持有练兵场出品虎符的人,即可享受负责人待遇进入领兵,无需通知负责人。

public class Principal{

    public static Soldier produceInfantry() {
        return new Infantry();
    }
    public static Soldier produceTrooper() {
        return new Trooper();
    }
}
public class Test {
    public static void main(String[] args) {
        Soldier infantry= Principal.produceInfantry();
        Soldier trooper= Principal.produceTrooper();
        infantry.fight();
        trooper.fight();
    }
}
  • ?现在诸葛亮想为刘备练一些弓兵。但是有一个问题,一个练兵场只能练那么多种兵,而且为了更专业,最好一个练兵场只专门练一种兵。

  • 诸葛锦囊:为弓兵建一个弓兵练兵场!

2 抽象工厂模式(Abstract Factory)

于是在诸葛亮改良之后,刘备同意为步兵、骑兵和弓兵分别建一个练兵场,诸葛亮作为所有练兵场的管理员,负责派发所有的虎符。
这时候想要领兵,按以下步骤,诸葛亮建对应的练兵场,将领到对应的练兵场,持有虎符,领兵。

public interface Soldier{
    void fight();
}
public class Infantry implements Soldier{
    @Override
    public void fight() {
        System.out.println("Infantry walk forward!");
    }
}
public class Archer implements Soldier{

    @Override
    public void fight() {
        System.out.println("Fire arrows!");
    }
}
public class InfantryFactory{

    public Soldier produce() {
      	return new Infantry();
    }
}
public class ArcherFactory{

    public Soldier produce() {
      	return new Archer();
    }
}
public class Test {
    public static void main(String[] args) {
        Factory infantryFactory= new InfantryFactory();
        Infantry infantry = infantryFactory.produce();
        infantry.fight();

        Factory archerFactory= new ArcherFactory();
        Archer archer = archerFactory.produce();
        archer.fight();
    }
}
  • ?现在,弓兵练起来了,诸葛亮开始考虑怎么得到箭。可以有两种途径,一个是自己造,一个是向曹操草船借箭。

  • 诸葛锦囊:有两个流水线,一个是造箭流水线,一个是借箭流水线!

3 建造者模式(Builder)

于是,总箭量有两个补充来源,一个是造箭工厂中造出来的箭,一个是草船上借出来的箭。
比如要造n根箭,就向诸葛亮上书,诸葛亮就new出n个工厂箭加入箭库。要借m根箭,就向诸葛亮上书,诸葛亮就new出m个操草船箭加入箭库。

public class ArrowBuilder {

    private List<Arrow> list = new ArrayList<Arrow>();

    public void produceByGrassboat(int count){
        for(int i=0; i<count; i++){
            list.add(new GrassboatArrow());
        }
    }

    public void produceByFactory(int count){
        for(int i=0; i<count; i++){
            list.add(new FactoryArrow());
        }
    }
}
public class Test {
    public static void main(String[] args) {
        ArrowBuilder arrowBuilder = new ArrowBuilder();
        // 草船借10根箭
        arrowBuilder.produceByGrassboat(10);
        // 工厂造5根箭
        arrowBuilder.produceByFactory(5);
    }
}

4 单例模式(Singleton)

诸葛亮作为丞相要发出独一无二的命令,所以军令状上面要有他的印章。但是怎么保证这个印章是只有他能造、且绝无仅有的呢?
幸运的是,诸葛亮有一个非常聪明的发明家妻子。
于是,只有他的妻子能造出这个印章,这保证了造印章的能力是私有的。
且妻子有,就相当于诸葛亮有,所以相当于诸葛亮永远持有一个且只有一个私有的静态的印章instance。
如果任何人要盖印,只能先找到诸葛亮,取得这独一无二的印章,然后调用盖印方法。

public class Seal{
    /* 私有构造方法,防止被实例化 */
    private Seal() {
    }

    /* 此处使用一个内部类来维护单例 */
    private static class SealFactory {
        private static Seal instance = new Seal();
    }

    /* 获取实例 */
    public static Seal getInstance() {
        return SealFactory.instance;
    }

    /* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */
    public Object readResolve() {
        return getInstance();
    }
}

5 原型模式(Prototype)

孙悟空可以用身上的毫毛变出和自己一模一样的猴子,我们管复制品叫猴A。
猴A毕竟还是孙悟空的毫毛,你敲一下猴A,孙悟空会有点刺痛。我们管这叫浅复制。
但是当六耳猕猴变成了假孙悟空时,你就算把六耳猕猴打成肉酱,孙悟空也没事。我们管这叫深复制。

public class SunWukong implements Cloneable {
 	
    private static final long serialVersionUID = 1L;
    private String string;

    private SerializableObject obj;
    
	public Object clone() throws CloneNotSupportedException { 
		SunWukong monkeyA = (SunWukong) super.clone(); 
		return monkeyA; 
	} 
} 
	public Object deepClone() throws IOException, ClassNotFoundException {

        /* 写入当前对象的二进制流 */
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(this);

        /* 读出二进制流产生的新对象 */
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray(
        ));
        ObjectInputStream ois = new ObjectInputStream(bis);
        return ois.readObject();
    }
    
    public String getString() {
        return string;
    }

    public void setString(String string) {
        this.string = string;
    }

    public SerializableObject getObj() {
        return obj;
    }

    public void setObj(SerializableObject obj) {
        this.obj = obj;
    }
}
class SerializableObject implements Serializable {
    private static final long serialVersionUID = 1L;
} 

6 适配器模式(Adapter)

6.1 类的适配器模式

唐僧对如何管住孙悟空感到烦恼,于是观音菩萨给了他一个漂亮的金丝帽。
这顶帽子有帽子的两个功能。一个是可以让别人看不出一个人头秃,从而增加颜值;另一个是尽量保证帽子能紧紧地套在佩戴者头上。
但是,不仅如此,这顶金丝帽还套着一个金箍。只要念咒,这个金箍收紧,戴上的人就会服从管教。

public class GoldHoop{
    public void tighten(){
        System.out.println("Tighten the Gold hoop......");
    }
}
public interface Hat{
    public void beingHandsome();
    public void tighten();
}
public class GoldHat extends GoldHoop implements Hat{

    @Override
    public void beingHandsome() {
        System.out.println("Handsome up......");
    }
}
  • ? 但是,GoldHoop如果直接和GoldHat产生联系,孙悟空可能会发现这个陷阱。所以唐僧要找别的方式把GoldHoop藏在GoldHat里面。

  • 观音的建议:让GoldHoop不是GoldHat的祖先,而是直接成为GoldHat的组成成分。

6.2 对象的适配器模式

于是唐僧把GoldHoop缝进了GoldHat的内部,这下它看起来就是个普通帽子了。
于是,孙悟空被唐僧诈骗,高兴地戴上了GoldHat。他因为GoldHat变帅了,却也因为帽子中的金箍,不得不跟随唐僧去西天取经。

public class GoldHat implements Hat{
	private GoldHoop goldHoop;

    public GoldHat (GoldHoop g){
        super();
        goldHoop=g;
    }
    @Override
    public void beingHandsome() {
        System.out.println("Handsome up......");
    }
    @Override
    public void tighten(){
        goldHoop.tighten();
    }
}

6.3 接口的适配器模式

西天取经时,藏经阁中有所有经书,但一旦进去就必须把里面的经书全带回去,包括一些无用的无字经书。
如果唐僧一行人只想要其中的有字大乘经书带回东土大唐,只能向实现了藏经阁的如来佛讨要有字大乘经书。

public interface ScriptureLibrary{
    public void bookHaveWord();
    public void bookDontHaveWord();
}
public abstract class Buddha implements ScriptureLibrary{
    public void bookHaveWord();
    public void bookDontHaveWord();
}
public class TangMonk extends Buddha {
    public void bookHaveWord(){
        System.out.println("Get book with word");
    }
}
public class Test {
    public static void main(String[] args) {
        Buddha tangMonk=new TangMonk();
        tangMonk.bookHaveWord();
    }
}

7 装饰模式(Decorator)

贾瑞瑞大爷一直觊觎王熙凤,以至于在一般波折后得了重病,这时跛足道人给了他一面叫做风月宝鉴的镜子,并且吩咐只可以看镜子的背面,不能看正面。
贾瑞看了镜子的背面,却上面的呈现出来的骷髅吓了一跳,然后忍不住看了镜子的正面,发现骷髅变成王熙凤美貌的模样。
色心上头的贾瑞没有意识到,镜子只是一个接口,不管是骷髅还是肉体都只是一种实现,但只有骷髅白骨才是所有人没有被修饰的模样。
最终贾瑞被白骨修饰成的肉身而迷了心智,最终失去了生命。

public interface Mirror{
    public void show();
}
public class Bone implements Mirror{
    @Override
    public void show() {
        System.out.println("Scary human skeleton");
    }
}
public class BeautifulFace implements Mirror{

    private Mirror bone;

    public BeautifulFace(Mirror bone){
        super();
        this.bone=bone;
    }

    @Override
    public void show() {
        bone.show();
        System.out.println("Beautiful face");
    }
}
public class Test {
    public static void main(String[] args) {
        Mirror back= new Bone();
        Mirror front = new BeautifulFace(back);
        front.show();
    }
}

8 代理模式(Proxy)

探春想将大观园的每一部分开发出对应的产业,但是一个人在这么多工作面前是分身乏术、且不够专业的。
所以贾家婆子齐上阵,成为不同营生的管理者,让专业的人做专业的事,用不同的途径来实现创收这个目标。

public interface Reformation {
    public void revenue();
}
public class BambooForest implements Reformation  {
    @Override
    public void revenue() {
        System.out.println("Make money");
    }
}
public class Vanilla implements Reformation {
    @Override
    public void revenue() {
        System.out.println("Make money");
    }
}
public class BambooForestManager implements Reformation {

    private Reformation field;

    public BambooForestManager(){
        super();
        field=new BambooForest();
    }

    @Override
    public void revenue() {
        work();
        field.revenue();
    }

    public void before(){
        System.out.println("Cut the bamboo");
    }
}
public class VanillaManager implements Reformation {

    private Reformation field;

    public BambooForestManager(){
        super();
        field=new Vanilla();
    }

    @Override
    public void revenue() {
        work();
        field.revenue();
    }

    public void before(){
        System.out.println("Reap vanilla");
    }
}

9 外观模式(Facade)

红楼梦人物之间的关系十分复杂,其间可能夹杂着爱情、友情、命运等情感。
但是,如果考虑到他们之间的亲戚关系,可能会无法共情像木石前盟、金玉良缘之类的美好关系。
所以我们把他们的亲戚关系放在一个Facade 类中,不直接在每个人的身上贴亲戚关系的标签(也即不让他们互相继承),降低人与人之间的耦合度。

public class Baoyu{

    public void fatherConnect(){
        System.out.println("baoyu's father");
    }
    public void motherConnect(){
        System.out.println("baoyu's mother");
    }
}
public class Tanchun{

    public void fatherConnect(){
        System.out.println("tanchun's father");
    }
    public void motherConnect(){
        System.out.println("tanchun's mother");
    }
}
public class Baochai{

    public void fatherConnect(){
        System.out.println("baochai's father");
    }
    public void motherConnect(){
        System.out.println("baochai's mother");
    }
}
public class Facade{
    private Baoyu baoyu;
    private Tanchun tanchun;
    private Baochai baochai;

    public Computer(){
        baoyu= new Baoyu();
        tanchun= new Tanchun();
        baochai= new Baochai();
    }

    public void motherConnect(){
        baoyu.motherConnect()
        System.out.println("and");
        baochai.motherConnect()
        System.out.println("are sister.");
    }

    public void fatherConnect(){
        baoyu.fatherConnect()
        System.out.println("and");
        tanchun.fatherConnect()
        System.out.println("are the same one.");
    }
}

10 桥接模式(Bridge)

宋江虽然没有什么战斗力,但是他的长处是把36天罡72地煞都团结在一起,所有的武将都遵从他的规定,并听从他的调用。
当打仗的时候,吴用经过宋江的授权,可以自由派遣任意武将上场,然后这些武将发挥自己的长处。这样,宋江和吴用不需要知道怎么战斗,武将也只需要遵从规定、听从指挥。

public interface MilitaryOfficer{
    public void fight();
}
public class LinChong implements MilitaryOfficer{

    @Override
    public void fight() {
        System.out.println("LinChong fighting");
    }
}
public class ShiJing implements MilitaryOfficer{

    @Override
    public void fight() {
        System.out.println("ShiJing fighting");
    }
}
public abstract class SongJiang{
    private MilitaryOfficer officer;

    public void setOfficer(MilitaryOfficer militaryOfficer){
        officer=militaryOfficer;
    }

    public MilitaryOfficer sendOfficer(){
        return officer;
    }

    public void fight(){
        officer.fight();
    }
}
public class WuYong extends SongJiang{
    public void fight(){
        sendOfficer().fight();
    }
}
public class Test {
    public static void main(String[] args) {
        SongJiang commander = new WuYong();

        ShiJing shiJing = new ShiJing();
        commander.setOfficer(shiJing);
        commander.fight();
    }
}

11 组合模式(Composite)

红楼梦有着复杂的人物亲戚关系,一般我们可以画一个族谱或者家谱来表示这个树状关系。

public class TreeNode {
    private String name;
    private TreeNode parent;
    private Vector<TreeNode> children = new Vector<TreeNode>();

    public TreeNode(String name){
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public TreeNode getParent() {
        return parent;
    }
    public void setParent(TreeNode parent) {
        this.parent = parent;
    }

    //添加孩子节点
    public void add(TreeNode node){
        children.add(node);
    }

    //删除孩子节点
    public void remove(TreeNode node){
        children.remove(node);
    }

    //取得孩子节点
    public Enumeration<TreeNode> getChildren(){
        return children.elements();
    }
}

12 享元模式(Flyweight)

孙悟空身上有100根超级毫毛,它们可以用来变成小猴。小猴有两个共有的属性:身高,体重。这些属性对于毫毛变的小猴来说都是一样的。但是在面对不同场景时,可能需要有持有不同武器的小猴,所以这个属性可以在实际造猴的时候设置。
当孙悟空要造猴的时候,他从剩余的毫毛中拔出一根,然后变成小猴。给小猴不同的武器来造就不同的小猴。当小猴没有用了的时候,就要对其进行回收,这时孙悟空会把小猴变回毫毛,以维持自己的毫毛池。

public class FurPool {
    private Vector<Fur> pool;

    /*公有属性*/
    private int height = 150;
    private int weight = 40;   
    Fur fur = null; 

    /*构造方法,做一些初始化工作*/
    private FurPool () {
        pool = new Vector<Fur>(poolSize);

        for (int i = 0; i < poolSize; i++) {
            try {
                Class.forName("com.ChangeToMonkey");
                fur = DriverManager.getFur(height , weight);
                pool.add(fur);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    /* 返回连接到连接池 */
    public synchronized void release() {
        pool.add(fur);
    }

    /* 返回连接池中的一根毫毛 */
    public synchronized Fur getFur() {
        if (pool.size() > 0) {
            Fur fur= pool.get(0);
            pool.remove(fur);
            return fur;
        } else {
            return null;
        }
    }
}

13 策略模式(strategy)

贾宝玉要从宴会上溜出去,他有几个可选的策略:一个是谎称北静王请他去做客,一个谎称自己生病了,一个谎称自己要做功课。但是这些策略都需要一个策略的支持,那就是在门外备好逃跑用的马。
所以贾宝玉会在每次需要溜走的时候,从策略接口中实现一个策略,然后执行逃脱计划escape(),其中的最后一步都是执行共有策略:备好逃跑用的马。

public interface IStrategy {
    public int escape();
}
public abstract class AbstractStrategy {
    public int[] runWithAHorse(){
    	System.out.println("Run with a horse");
    }
}
public class VisitBei extends AbstractStrategy implements IStrategy {

    @Override
    public int escape() {
        System.out.println("Pretend Visit Bei");
        runWithAHorse();
    }
}
public class Ill extends AbstractStrategy implements IStrategy {

    @Override
    public int escape() {
        System.out.println("Pretend Ill");
        runWithAHorse();
    }
}
public class DoHomework extends AbstractStrategy implements IStrategy {

    @Override
    public int escape() {
        System.out.println("Pretend Do Homework ");
        runWithAHorse();
    }
}
public class Test {
    public static void main(String[] args) {
        IStrategy doHomework = new DoHomework();
        doHomework.escape();
    }
}

14 模板方法模式(Template Method)

贾政快要结束他的出差,回贾府检查贾宝玉的作业了。一点书法没练的贾宝玉快吓出病,于是众姐妹开始帮贾宝玉伪造书法作业。
伪造书法作业不是一件简单的事情,需要贾宝玉自己先给出一个自己的笔迹模板,让姐妹们模仿。虽然都是写同样的笔迹,但是为了更好的搪塞过去,每个人帮忙写的内容都不一样。
最后,贾宝玉用不同的内容、同样的笔迹,过了贾政的严父关。

public abstract class AbstractStrategy {
    public int[] runWithAHorse(){
    	System.out.println("Run with a horse");
    }
    public final int escape(){
    	System.out.println("Run with a horse");
        return escape();
    }
    abstract public int escape();
}
public class VisitBei extends AbstractStrategy {

    @Override
    public int escape() {
        System.out.println("Pretend Visit Bei");
    }
}
public class Ill extends AbstractStrategy {

    @Override
    public int escape() {
        System.out.println("Pretend Ill");
    }
}
public class DoHomework extends AbstractStrategy implements IStrategy {

    @Override
    public int escape() {
        System.out.println("Pretend Do Homework ");
    }
}
public class Test {
    public static void main(String[] args) {
        AbstractStrategy doHomework = new DoHomework();
        doHomework.escape();
    }
}

15 观察者模式(Observer)

每个注册为贾府管理者的人,都可以接收到贾家时刻的变化信息。这个信息由分管不同事务的高级婆子进行通知。
在几十年里,贾母、王夫人、王熙凤先后注册为贾府管理者,加入贾府事务通知群。
这几日,巡视的婆子发现府内一角有赌博行为,于是行动起来,调用notifyObservers权限,一次性通知了所有贾府管理者。

public interface Administrator{
    public void update();
}
public class JiaMu implements Administrator{
    @Override
    public void update() {
        System.out.println("JiaMu has received.");
    }
}
public class WangXifeng implements Administrator{
    @Override
    public void update() {
        System.out.println("WangXifeng has received.");
    }
}
public class Mrs.Wang implements Administrator{
    @Override
    public void update() {
        System.out.println("Mrs.Wang has received.");
    }
}
public interface Stewards{
    /*增加观察者*/
    public void add(Administrator ad);

    /*删除观察者*/
    public void del(Administrator ad);

    /*通知所有的观察者*/
    public void notifyObservers();

    /*自身的操作*/
    public void operation();
}
public abstract class AbstractSteward implements Stewards{
    private Vector<Administrator> vector = new Vector<Administrator>();
    @Override
    public void add(Administrator ad) {
        vector.add(ad);
    }

    @Override
    public void del(Administrator ad) {
        vector.remove(ad);
    }

    @Override
    public void notifyObservers() {
        Enumeration<Administrator> enumo = vector.elements();
        while(enumo.hasMoreElements()){
            enumo.nextElement().update();
        }
    }
}
public class Steward extends AbstractSteward{
    @Override
    public void operation() {
        System.out.println("update self!");
        notifyObservers();
    }
}
public class Test {
    public static void main(String[] args) {
        AbstractSteward steward= new Steward();
        steward.add(new WangXifeng());
        steward.add(new JiaMu());
        steward.operation();
    }
}

16 迭代子模式(Iterator)

16.1 implements Iterator

16.2 implements Collection

17 责任链模式(Chain of Responsibility)

大观园建成之后需要对里面的建筑起名,于是贾政又想通过这个方法来考察贾宝玉的文采。
贾政带着贾宝玉逛了一圈园子,然后让贾宝玉为每个院子起名。
但是贾宝玉起的名并不能作为最终结果,还是需要元春省亲的时候最终敲定。
贾政->贾宝玉->元春,这就是责任链。

public interface Handler {
    public void operator();
}
public abstract class AbstractHandler {

    private Handler handler;

    public Handler getHandler() {
        return handler;
    }

    public void setHandler(Handler handler) {
        this.handler = handler;
    }
}
public class MyHandler extends AbstractHandler implements Handler {

    private String name;

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

    @Override
    public void operator() {
        System.out.println(name+" deal!");
        if(getHandler()!=null){
            getHandler().operator();
        }
    }
}
public class Test {

    public static void main(String[] args) {
        MyHandler h1 = new MyHandler("JiaZheng");
        MyHandler h2 = new MyHandler("JiaBaoyu");
        MyHandler h3 = new MyHandler("JiaYuanchun");

        h1.setHandler(h2);
        h2.setHandler(h3);

        h1.operator();
    }
}

18 命令模式(Command)

在火烧联营时,诸葛亮下令让关羽去抓曹操。
诸葛亮指定并发出抓曹操的命令,命令中指定了接收人是关羽,于是命令的执行即相当于关羽的进行了抓曹操行动。
诸葛亮不会去关注到底关羽是怎么抓曹操的,只会要求关羽一定得去抓曹操。

public interface Command {
    public void exe();
}
public class MyCommand implements Command{
    private GuangYu receiver;

    public MyCommand(GuanYu receiver){
        this.receiver=receiver;
    }

    @Override
    public void exe() {
        receiver.action();
    }
}
public class GuanYu {
    public void action(){
        System.out.println("Command received.");
    }
}
public class ZhugeLiang{
    private Command command;

    public Commander(Command command){
        this.command=command;
    }

    public void action(){
        command.exe();
    }
}

19 备忘录模式(Memento)

红楼梦中众女儿的前世今生都被记录在了薄命司的金陵一册中。
金陵一册用判词和图画记录对众女儿命运,薄命司是存储金陵一册的地方。

public class JinlingMemento {

    private String value;

    public JinlingMemento(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}
public class IllfatedDepartment{

    private JinlingMemento memento;

    public IllfatedDepartment(JinlingMemento memento) {
        this.memento = memento;
    }

    public JinlingMemento getMemento() {
        return memento;
    }

    public void setMemento(JinlingMemento memento) {
        this.memento = memento;
    }
}
public class CourtVerdict{
    private String value;

    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public Original(String value) {
        this.value = value;
    }
    public JinlingMemento createMemento(){
        return new JinlingMemento(value);
    }

    public void restoreMemento(JinlingMemento memento){
        this.value = memento.getValue();
    }
}
public class Test {

    public static void main(String[] args) {

        // 创建原始类
        CourtVerdict origin = new CourtVerdict("可叹停机德,堪怜咏絮才。");

        // 创建备忘录
        IllfatedDepartment storage = new IllfatedDepartment(origin.createMemento());

        // 修改原始类的状态
        System.out.println("初始化状态为:" + origin.getValue());
        origi.setValue("玉带林中挂,金钗雪里埋。");
        System.out.println("修改后的状态为:" + origin.getValue());

        // 回复原始类的状态
                origin.restoreMemento(storage.getMemento());
        System.out.println("恢复后的状态为:" + origin.getValue());
    }
}

20 状态模式(State)

在贾府的就餐流程中,有非常多种状态。
要先噤声吃饭、再洗手、再用茶漱口、最后再喝茶,每个状态对应不同的操作。

public class State {

    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public void methodEat(){
        System.out.println("Silence and Eat!");
    }

    public void methodWash(){
        System.out.println("Wash hand!");
    }

    public void methodGargle(){
        System.out.println("Gargle with tea!");
    }

    public void methodDrink(){
        System.out.println("Drink tea!");
    }
}
public class Daiyu{

    private State state;

    public Context(State state) {
        this.state = state;
    }

    public State getState() {
        return state;
    }

    public void setState(State state) {
        this.state = state;
    }

    public void method() {
        if (state.getValue().equals("Eat")) {
            state.methodEat();
        } else if (state.getValue().equals("Wash"))
            state.methodWash();
        } else if (state.getValue().equals("Gargle"))
            state.methodGargle();
        } else if (state.getValue().equals("Drink"))
            state.methodDrink();
        }
    }
}
public class Test {
    public static void main(String[] args) {
        State state = new State();
        Daiyu daiyu= new Daiyu(state);

        state.setValue("Eat");
        daiyu.methodEat();
        
        state.setValue("Wash");
        daiyu.methodWash();
        
        state.setValue("Gargle");
        daiyu.methodGargle();

        state.setValue("Drink");
        daiyu.methodEat();
    }
}

21 访问者模式(Visitor)

寿怡红群芳开夜宴:贾宝玉过生日没过瘾,在晚上还邀请众姐妹到怡红院玩抽花签。

众姐妹想参与抽花签,需要经历以下流程:
怡红院接受拜访;
拜访人执行拜访功能;
在拜访中执行怡红院的抽花签功能。

public interface Visitor {
    public void visit(Subject sub);
}
public class Daiyu implements Visitor {

    @Override
    public void visit(Building sub) {'
    	System.out.println("Daiyu "+sub.playDraw())
    }
}
public interface Building{
    public void accept(Visitor visitor);
    public String playDraw();
}
public class YiHongYuan implements Building{

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    @Override
    public String playDraw() {
        return "play draw lots";
    }
}
public class Test {
    public static void main(String[] args) {
        Visitor visitor = new Daiyu();
        Building sub = new YiHongYuan();
        sub.accept(visitor);
    }
}

22 中介者模式(Mediator)

大观园的众屋舍是在贾宝玉和众姐妹搬入大观园的前就建好的。
这时候的大观园是一个中介,当贾宝玉和众姐妹搬入时,他们通过选择自己在大观园中的位置来体现互相的亲疏远近,而无需尴尬的互相表明依赖关系,这样不利于人与人之间相处的和谐。

public abstract class Role{

    private Mediator mediator;

    public Mediator getMediator(){
        return mediator;
    }
    public Role(Mediator mediator) {
        this.mediator = mediator;
    }

    public abstract void play();
}
public class Daiyu extends Role{

    public Daiyu(Mediator mediator){
        super(mediator);
    }

    @Override
    public void play() {
        System.out.println("Daiyu play!");
    }
}
public class Baoyu extends Role{

    public Baoyu(Mediator mediator){
        super(mediator);
    }

    @Override
    public void play() {
        System.out.println("Baoyu play!");
    }
}
public interface Mediator {
    public void createMediator();
    public void playTogether();
}
public class GrandGarden implements Mediator {

    private Role daiyu;
    private Role baoyu;

    public Role getUser1() {
        return daiyu;
    }

    public Role getUser2() {
        return baoyu;
    }

    @Override
    public void createMediator() {
        daiyu= new Daiyu(this);
        baoyu= new Baoyu(this);
    }

    @Override
    public void playTogether() {
        daiyu.play();
        System.out.println("and");
        baoyu.play();
    }
}
public class Test { 
	 public static void main(String[] args) { 
		 Mediator mediator = new GrandGarden(); 
		 mediator.createMediator(); 
		 mediator.playTogether(); 
 	} 
 } 

23 解释器模式(Interpreter)

etc.etc. 这个模式用的好少,懒得写故事了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值