设计模式--简化解释(一)——建立型设计模式

1.建立型设计模式
2.结构型设计模式
3.行为型设计模式java

建立型设计模式

简而言之面试

建立型设计模式关注的是如何实例化一个或者一组相关的对象。

维基百科编程

在软件工程中,建立型设计模式是用于解决对象建立机制,尝试在指定场景下使用合理的方式来建立对象的设计模式。基本的建立方式对致使设计问题或者增长设计的复杂度。建立型设计模式经过一些控制对象建立的手段来解决这些问题。

? 简单工厂

现实例子segmentfault

考虑一下,你须要建造一个房子,而后须要几扇门。若是每次须要一扇门的时候,你都穿上木匠的衣服而后在房间里左门会形成很大的混乱。取而代之是你须要买一个从工厂里作好的。

简而言之设计模式

对客户端来讲,简单工厂模式仅仅生成一个实例,不须要暴露给客户端人户实例化的逻辑。

维基百科说ide

在面向对象编程中(OOP),工厂是一个用于建立对象的对象,正式的工厂是一个方法或者函数,在某些方法调用的时候返回不一样的原型或者对象,咱们认为这个对象是新的。

编程实例
首先咱们有一个们的接口和实现函数

public interface Door {
    float getWidth();
    float getHeight();
}
public class WoodenDoor implements Door {
    private float width;
    private float height;

    public WoodenDoor(float width, float height) {
        this.width = width;
        this.height = height;
    }

    @Override
    public float getWidth() {
        return 0;
    }

    @Override
    public float getHeight() {
        return 0;
    }
}

而后咱们须要一个生产并返回门的工厂ui

public class DoorFactory {
    public static Door makeDoor(float width,float height)
    {
        return new WoodenDoor(width,height);
    }
}

使用方式以下this

Door door = DoorFactory.makeDoor(1200L,2100L);
System.out.println("Door Width:"+door.getWidth());
System.out.println("Door Height:"+door.getHeight());

什么时候使用
当建立一个不只仅是几条赋值语句同时包含一些逻辑的对象的时候,把建立对象的代码放到一个专用的工厂中而不是处处赋值相同的代码,这是情理之中的。翻译

? 工厂方法

现实例子

考虑一我的事部经理的例子. 不可能全部的岗位都有一我的来面试. 根据职位空缺,他将面试的步骤安排给不一样的人.

简而言之

提供一种将实例化逻辑委托给子类的方式.

维基百科说

在给予类的编程中,工厂方法模式是一个建立型的模式,这个模式用于解决建对象的问题而无需指定要建立的精确的类。经过调用工厂方法(在接口中指定并由子类实现,或者在基类中实现),或者经过派生类(而不是调用构造函数)来实现,这是经过建立对象来完成的。

编程示例
参考上边人事部经理的例子。首先咱们有一个面试官的接口和一些实现。

public interface Inteviewer {
    void askQuestions();
}
public class Developer implements Inteviewer {
    @Override
    public void askQuestions() {
        System.out.println("Ask about Design Patterns");
    }
}
public class CommunityExecutive implements Inteviewer {
    @Override
    public void askQuestions() {
        System.out.println("Ask about community build");
    }
}

如今咱们建立 HiringManager

public abstract class HiringManager {
    protected abstract Inteviewer makeInteviewer();

    public void takeInteview()
    {
        Inteviewer inteviewer = makeInteviewer();
        inteviewer.askQuestions();
    }
}

如今和人子类均可以实现该类来提供须要的面试官

public class DevelopmentManager extends HiringManager {
    @Override
    protected Inteviewer makeInteviewer() {
        return new Developer();
    }
}
public class CommunityManager extends HiringManager {
    @Override
    protected Inteviewer makeInteviewer() {
        return new CommunityExecutive();
    }
}

使用举例

public class Client {
    public static void main(String[] args) {
        HiringManager manager = new DevelopmentManager();
        manager.takeInteview();

        manager = new CommunityManager();
        manager.takeInteview();
    }
}

什么时候使用?
当一个类中有一些通用的处理可是子类须要在运行时决定的时候使用。换句话说,客户端不知道须要的精确的子类。

? 抽象工厂

现实举例

扩展咱们的简单工厂模式的门的例子。考虑到你的需求,你可能从一个木门的商店购买一个木门,从一个铁门的商店购买一个铁门,或者从另外的相关的商店购买一个PVC门。除此以外你可能须要一个有不一样技能的伙计帮你装门,例如木匠来装木门,焊接工装铁门。正如你看到的那样,如今门之间有一个依赖,木门须要木匠,铁门须要焊接工等等。

简而言之

一个工厂的工厂。一个工厂在不指定具体的类的状况下将独立但相关的工程组合在一块儿。

维基百科说

抽象工厂模式提供了一种方式来封装一度独立的工厂,这些工厂有相同的主题当时没有指定具体的类。

编程示例

翻译上边门的例子. 首先咱们有门的接口和几个门的实现

public interface Door {
    String getDescription();
}
public class WoodenDoor implements Door {
    @Override
    public String getDescription() {
        return "I am a wooden door";
    }
}
public class IronDoor implements Door {
    @Override
    public String getDescription() {
        return "I am an iron door";
    }
}

而后每一种门咱们有一些安装专家

public interface DoorFittingExpert {
    String getDescription();
}
public class Carpenter implements DoorFittingExpert {
    @Override
    public String getDescription() {
        return "I can only fit wooden doors";
    }
}
public class Welder implements DoorFittingExpert {
    @Override
    public String getDescription() {
        return "I can only fit iron doors";
    }
}

如今咱们须要一个抽象工厂来帮咱们决定相关对象的族。例如木门工厂须要生产木门和木门安装专家,铁门工厂须要生产铁门和铁门安装专家。

public interface DoorFactory {
    Door makeDoor();
    DoorFittingExpert makeFittingExper();
}
public class WoodenDoorFactory implements DoorFactory {
    @Override
    public Door makeDoor() {
        return new WoodenDoor();
    }

    @Override
    public DoorFittingExpert makeFittingExper() {
        return new Carpenter();
    }
}
public class IronDoorFactory implements DoorFactory {
    @Override
    public Door makeDoor() {
        return new IronDoor();
    }

    @Override
    public DoorFittingExpert makeFittingExper() {
        return new Welder();
    }
}

使用方式以下:

DoorFactory doorFactory = new WoodenDoorFactory();
        Door door = doorFactory.makeDoor();
        DoorFittingExpert expert = doorFactory.makeFittingExper();
        System.out.println("Door:"+door.getDescription());
        System.out.println("Expert:"+expert.getDescription());

正如上边看到的同样,木门工厂封装了carpenterwooden door,铁门工厂封装了iron doorwelder.所以工厂帮咱们确信每个建立的门都不会有错误的安装的专家

什么时候使用
当有相关的复杂的建立逻辑的依赖的时候

? 建造者

现实举例

设想一下你在Hardee,你要点餐,咱们会说:Big Hardee,他们不会问任何 问题就会把饭端过来。这是一个简单工厂的例子。可是有种状况下建立逻辑包含几个步骤。例如你想吃一个自助的Subway,汉堡怎么作,例如面包用什么样的,用什么样的酱汁,想要什么样的奶酪。这种状况下,建造者模式将会拯救咱们。

简而言之

避免构造函数污染的状况下为对象创造不一样的特性。当一个对象有多个特性或者建立对象包含几个步骤的时候使用。

维基百科说

建造者模式是一种对象建立软件设计模式,其目的是找到一种解决方案,以解决可伸缩构造函数的反模式。

说道这里,让我添加一点关于伸缩构造函数反模式的内容。在某些地方,咱们都看到了以下的构造函数。:

public Deal(int size, boolean cheese ,boolean pepperoni, boolean tomato, boolean lettuce)
{
}

正如你所看到的;构造函数参数的数量很快就会失去控制,而且很难理解参数的排列。另外,若是你想在将来增长更多的选项,这个参数列表还能够继续增加。这被称为伸缩构造函数反模式。

程序示例
明智的选择是使用建造者模式。首先咱们要有一个咱们要作的汉堡(burger)

package com.suifeng.designpattern.builder;

public class Burger {
    private int size;
    private boolean cheese;
    private boolean pepperoni;
    private boolean lettuce;
    private boolean tomato;

    public Burger(BurgerBuilder builder)
    {
        this.size = builder.size;
        this.cheese=builder.cheese;
        this.pepperoni = builder.pepperoni;
        this.lettuce = builder.lettuce;
        this.tomato = builder.tomato;
    }

    @Override
    public String toString() {
        return "Burger{" +
                "size=" + size +
                ", cheese=" + cheese +
                ", pepperoni=" + pepperoni +
                ", lettuce=" + lettuce +
                ", tomato=" + tomato +
                '}';
    }

    static class BurgerBuilder{
        private int size;
        private boolean cheese;
        private boolean pepperoni;
        private boolean lettuce;
        private boolean tomato;

        public BurgerBuilder(int size) {
            this.size = size;
        }

        public BurgerBuilder addCheese()
        {
            this.cheese = true;
            return this;
        }

        public BurgerBuilder addPepperoni()
        {
            this.pepperoni = true;
            return this;
        }

        public BurgerBuilder addLettuce()
        {
            this.lettuce = true;
            return this;
        }

        public BurgerBuilder addTomato()
        {
            this.tomato = true;
            return this;
        }

        public Burger build()
        {
            return new Burger(this);
        }
    }
}

使用方式以下

Burger burger = new Burger.BurgerBuilder(12).addCheese().addLettuce().build();
        System.out.println(burger);

什么时候使用
当一个对象有几个特性而且须要避免构造器伸缩。与工厂模式的主要不一样是:工厂模式的建立过程只有一个步骤而建造者模式须要多个步骤。

? 原型

现实举例

还记得多里吗?就是那只被克隆的山羊。咱们不关注细节,这里的关键就是克隆。

简而言之

经过克隆的方式根据现有对象来建立新对象

维基百科说

原型模式是软件开发中的一个建立型设计模式。当要建立的对象类型由一个原型实例决定时,使用原型模式,该实例被克隆以产生新的对象。

简而言之,它容许您建立一个现有对象的副本,并根据您的须要修改它,而不是从头开始建立一个对象并设置它。

Programmatic Example

Java中可使用clone方法

public class Sheep implements Cloneable {

    private String name;
    private String category;

    public Sheep(String name, String category) {
        this.name = name;
        this.category = category;
    }

    public String getName() {
        return name;
    }

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

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    @Override
    public String toString() {
        return "Sheep{" +
                "name='" + name + '\'' +
                ", category='" + category + '\'' +
                '}';
    }

    public Sheep clone()
    {
        Object obj = null;

        try {
            obj =super.clone();

            return (Sheep) obj;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

        return null;
    }
}

克隆方式以下

public class Client {
    public static void main(String[] args) {
        Sheep sheep = new Sheep("Jolly","Mountain Sheep");

        Sheep dolly = sheep.clone();
        dolly.setName("Dolly");

        System.out.println(dolly);
    }
}

什么时候使用?

当须要的对象与存在的对象类似的时候或者相比于克隆建立成本比较高的状况.

? 单例

现实举例

同一时间一个国家只有一个总统。 当指责须要的时候,采起行动的是同一个总统. 在这里总统就是单例的

简而言之

一个特定的类确保只建立一个对象。

维基百科说

在软件工程中,单例模式是一种软件设计模式,它将类的实例化限制为一个对象。 当须要一个对象来协调整个系统中的操做时,这颇有用。

单例模式实际上被认为是一种反模式,应该避免过分使用。它并不必定是坏的,而且能够有一些有效的用例,可是应该谨慎使用,由于它在您的应用程序中引入了一个全局状态,而且在一个地方对它进行更改可能会影响到其余领域,所以调试可能变得很是困难。另外一件很差的事情是,它使您的代码紧密耦合,另外对单例对象的模拟是困难的。

编程示例
建立一个单例,须要将构造函数私有,禁用可控和扩展,经过建立一个静态的变量来保存实例。

public class President {
    private static President INSTANCE ;

    private President()
    {

    }

    public static President getInstance()
    {
        if(INSTANCE == null)
        {
            INSTANCE = new President();
        }

        return INSTANCE;
    }


}

使用方式以下

President president1 = President.getInstance();
        President president2 = President.getInstance();

        System.out.println(president1 == president2);
相关文章
相关标签/搜索