工厂模式详解

  • 1. 简单工厂模式
    • 1.1 需求分析
    • 1.2 使用传统方式实现
      • 1.2.1 类图
      • 1.2.2 代码实现
        • 1.2.2.1 新建pizza抽象类
        • 1.2.2.2 希腊披萨实现类
        • 1.2.2.3 奶酪披萨实现类
        • 1.2.2.4 订购披萨类
        • 1.2.2.5 披萨商店类
        • 1.2.2.5 运行结果
      • 1.2.3 传统方式优缺点分析
    • 1.3 改进思路
    • 1.4 什么是简单工厂模式
      • 1.4.1 新建一个简单工厂类,用于生成pizza
      • 1.4.2 修改订购披萨类
      • 1.4.3 修改披萨商店类
    • 1.5 简单工厂又叫静态工厂
  • 2. 工厂方法模式
    • 2.1 需求分析
      • 2.1.1 思路1:使用简单工厂模式
      • 2.1.2 思路2:使用工厂方法模式
    • 2.2 什么是工厂方法模式?
      • 2.2.1 工厂方法模式设计方案
    • 2.3 代码实现
      • 2.3.1 类图
      • 2.3.2 上代码
        • 2.3.2.1 披萨类
        • 2.3.2.2 四个实现类
        • 2.3.2.3 订购披萨父类
        • 2.3.2.3 两个实现类
        • 2.3.2.4 披萨商店类,主类
        • 2.3.2.5 运行结果
  • 3. 抽象工厂模式
    • 3.1 什么是抽象工厂模式
    • 3.2 类图
    • 3.3 代码实现
      • 3.3.1 披萨类
      • 3.3.2 4个实现类
      • 3.3.3 抽象工厂接口
      • 3.3.4 两个重新工厂的实现类
      • 3.3.5 订购披萨类
      • 3.3.6 披萨商店类
      • 3.3.7 运行结果
  • 4. 工厂模式JDK里的使用
  • 5. 工厂模式小结

1. 简单工厂模式

1.1 需求分析

看一个披萨的项目:要便于披萨种类的扩展,要便于维护。

  1. 披萨的种类很多,比如GreekPizz,CheesePizz等
  2. 披萨的制作工序有prepare,bake,cut,box
  3. 完成披萨店订购功能

1.2 使用传统方式实现

1.2.1 类图

1.2.2 代码实现

1.2.2.1 新建pizza抽象类

package factory.simplefactory.pizzastore.pizza;/*** @author LongXi* @create 2021-07-31 8:47*/
//将Pizza做成抽象类
public abstract class Pizza {//名字protected String name;//准备原材料,不同的披萨不一样,因此我们做成抽象方法public abstract void prepare();//烘烤public void bake(){System.out.println(name + " baking;");}public void cut(){System.out.println(name + " cutting;");}public void box(){System.out.println(name + " boxing;");}public void setName(String name){this.name = name;}}

1.2.2.2 希腊披萨实现类

package factory.simplefactory.pizzastore.pizza;/*** @author LongXi* @create 2021-07-31 8:52*/
public class GreekPizza extends Pizza{@Overridepublic void prepare() {System.out.println("给制作希腊披萨,准备原材料");}
}

1.2.2.3 奶酪披萨实现类

package factory.simplefactory.pizzastore.pizza;/*** @author LongXi* @create 2021-07-31 8:52*/
public class CheesePizza extends Pizza{@Overridepublic void prepare() {System.out.println("给制作奶酪披萨,准备原材料");}
}

1.2.2.4 订购披萨类

package factory.simplefactory.pizzastore.order;import factory.simplefactory.pizzastore.pizza.CheesePizza;
import factory.simplefactory.pizzastore.pizza.GreekPizza;
import factory.simplefactory.pizzastore.pizza.Pizza;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;/*** @author LongXi* @create 2021-07-31 8:55*/
public class OrderPizza {public OrderPizza() {Pizza pizza = null;String orderType;//订购披萨类型do {orderType = getType();if (orderType.equals("greek")){pizza = new GreekPizza();pizza.setName("希腊披萨");}else if(orderType.equals("cheese")){pizza = new CheesePizza();pizza.setName("奶酪披萨");} else {break;}//输出披萨制作过程pizza.prepare();pizza.bake();pizza.cut();pizza.box();}while(true);}//加一个方法,可以获取客户希望订购的披萨种类private String getType(){try {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));System.out.println("请输入要订购的pizza种类:");String str = null;str = br.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}}
}

1.2.2.5 披萨商店类

package factory.simplefactory.pizzastore.order;/*** @author LongXi* @create 2021-07-31 9:08*/
public class pizzaStore {public static void main(String[] args) {new OrderPizza();}
}

1.2.2.5 运行结果

请输入要订购的pizza种类:
greek
给制作希腊披萨,准备原材料
希腊披萨 baking;
希腊披萨 cutting;
希腊披萨 boxing;
请输入要订购的pizza种类:
cheese
给制作奶酪披萨,准备原材料
奶酪披萨 baking;
奶酪披萨 cutting;
奶酪披萨 boxing;
请输入要订购的pizza种类:
lolProcess finished with exit code 0

1.2.3 传统方式优缺点分析

  1. 优点:比较好理解,简单易操作
  2. 缺点:违反了设计模式的OCP原则,即对扩展开放,对修改关闭。即当我们给类增加新功能的时候,尽量不修改代码,或者尽可能少修改代码。

假如我们现在增加一个新的种类披萨:胡椒披萨

胡椒披萨实现类

package factory.simplefactory.pizzastore.pizza;/*** @author LongXi* @create 2021-07-31 12:11*/
public class PepperPizza extends Pizza{@Overridepublic void prepare() {System.out.println("给制作胡椒披萨,准备原材料");}
}

订购披萨类也需要响应的更改,加入胡椒披萨判断分支

    public OrderPizza() {Pizza pizza = null;String orderType;//订购披萨类型do {orderType = getType();if (orderType.equals("greek")){pizza = new GreekPizza();pizza.setName("希腊披萨");}else if(orderType.equals("cheese")){pizza = new CheesePizza();pizza.setName("奶酪披萨");} else if(orderType.equals("pepper")){pizza = new PepperPizza();pizza.setName("胡椒披萨");break;}//输出披萨制作过程pizza.prepare();pizza.bake();pizza.cut();pizza.box();}while(true);}

执行结果

请输入要订购的pizza种类:
pepper
给制作胡椒披萨,准备原材料
胡椒披萨 baking;
胡椒披萨 cutting;
胡椒披萨 boxing;
请输入要订购的pizza种类:

1.3 改进思路

分析:修改代码可以接受,但是如果我们在其他的地方也有创建Pizza的代码,就意味着,也需要修改,而创建Pizza的代码,往往有多处。
思路:把创建Pizza对象封装到一个类张,这样我们有新的Pizza种类是,只需要修改该类就可,其他有创建到Pizza对象的代码就不需要修改了,这就是简单工厂模式。

1.4 什么是简单工厂模式

  1. 简单工厂模式是属于创建型模式,是工厂模式的一种。**简单工厂模式是又一个工厂对象决定创建出哪一种产品类的实例。**简单工厂模式是工厂模式家族中最简单实用的模式。
  2. 简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为(代码)
  3. 在软件开发中,当我们会用到大量的创建某种,某类或者某批对象时,就会使用到工厂模式。

类图:

1.4.1 新建一个简单工厂类,用于生成pizza

package factory.simplefactory.pizzastore.order;import factory.simplefactory.pizzastore.pizza.CheesePizza;
import factory.simplefactory.pizzastore.pizza.GreekPizza;
import factory.simplefactory.pizzastore.pizza.PepperPizza;
import factory.simplefactory.pizzastore.pizza.Pizza;/*** @author LongXi* @create 2021-07-31 12:29*/
//简单工厂模式
public class SimpleFactory {//根据OrderType返回Pizza对象public Pizza createPizza(String orderType){Pizza pizza = null;System.out.println("使用简单工厂模式");if (orderType.equals("greek")){pizza = new GreekPizza();pizza.setName("希腊披萨");}else if(orderType.equals("cheese")){pizza = new CheesePizza();pizza.setName("奶酪披萨");} else if(orderType.equals("pepper")){pizza = new PepperPizza();pizza.setName("胡椒披萨");}return pizza;}
}

1.4.2 修改订购披萨类

package factory.simplefactory.pizzastore.order;import factory.simplefactory.pizzastore.pizza.Pizza;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;/*** @author LongXi* @create 2021-07-31 8:55*/
public class OrderPizza {/* public OrderPizza() {Pizza pizza = null;String orderType;//订购披萨类型do {orderType = getType();if (orderType.equals("greek")){pizza = new GreekPizza();pizza.setName("希腊披萨");}else if(orderType.equals("cheese")){pizza = new CheesePizza();pizza.setName("奶酪披萨");} else if(orderType.equals("pepper")){pizza = new PepperPizza();pizza.setName("胡椒披萨");} else {break;}//输出披萨制作过程pizza.prepare();pizza.bake();pizza.cut();pizza.box();}while(true);}*/public  OrderPizza (SimpleFactory factory){this.setSimpleFactory(factory);}//定义一个简单工厂对象SimpleFactory simpleFactory;Pizza pizza = null;public void setSimpleFactory(SimpleFactory simpleFactory) {this.simpleFactory = simpleFactory;do {pizza = this.simpleFactory.createPizza(this.getType());if (pizza != null){pizza.prepare();pizza.bake();pizza.cut();pizza.box();} else {System.out.println("对不起,没有该种类的披萨,订购披萨失败");break;}}while(true);}//加一个方法,可以获取客户希望订购的披萨种类private String getType(){try {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));System.out.println("请输入要订购的pizza种类:");String str = null;str = br.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}}
}

1.4.3 修改披萨商店类

package factory.simplefactory.pizzastore.order;/*** @author LongXi* @create 2021-07-31 9:08*/
public class pizzaStore {public static void main(String[] args) {//new OrderPizza();new OrderPizza(new SimpleFactory());System.out.println("退出程序");}
}

这样我们就完成了改进,如果再追加一种披萨,我们只需要更改简单工厂类就可以了,而不用去更改订购披萨的类。

1.5 简单工厂又叫静态工厂

2. 工厂方法模式

2.1 需求分析

披萨项目的新需求:客户在点披萨时,可以点不同口味的披萨,比如:北京的奶酪披萨,北京的胡椒披萨或者是伦敦的奶酪披萨,伦敦的胡椒披萨。

2.1.1 思路1:使用简单工厂模式

创建不用的简单工厂类,比如BJPizzaSimpleFactory, LDPizzaSimpleFactory等等,从当前这个案例来说,也是可以的。
但是考虑到项目的规模,以及软件的可维护性、可扩展性并不是特别好。

2.1.2 思路2:使用工厂方法模式

2.2 什么是工厂方法模式?

定义了一个创建对象的抽象方法,由子类决定要实例化的类。
工厂方法模式的核心思想是:将对象的实例化推迟到子类。

2.2.1 工厂方法模式设计方案

将披萨项目的实例化功能抽象成抽象方法,在不同口类点餐子类中具体实现。

2.3 代码实现

2.3.1 类图

2.3.2 上代码

2.3.2.1 披萨类

package factory.factoryMethod.pizzastore.pizza;/*** @author LongXi* @create 2021-07-31 8:47*/
//将Pizza做成抽象类
public abstract class Pizza {//名字protected String name;//准备原材料,不同的披萨不一样,因此我们做成抽象方法public abstract void prepare();//烘烤public void bake(){System.out.println(name + " baking;");}public void cut(){System.out.println(name + " cutting;");}public void box(){System.out.println(name + " boxing;");}public void setName(String name){this.name = name;}}

2.3.2.2 四个实现类

/*** @author LongXi* @create 2021-07-31 13:15*/
public class BJCheesePizza extends Pizza{@Overridepublic void prepare() {setName("北京奶酪披萨");System.out.println("北京奶酪披萨 准备原材料");}
}
/*** @author LongXi* @create 2021-07-31 13:15*/
public class BJPepperPizza extends Pizza{@Overridepublic void prepare() {setName("北京胡椒披萨");System.out.println("北京胡椒披萨 准备原材料");}
}
/*** @author LongXi* @create 2021-07-31 13:15*/
public class LDCheesePizza extends Pizza{@Overridepublic void prepare() {setName("伦敦奶酪披萨");System.out.println("伦敦奶酪披萨 准备原材料");}
}
/*** @author LongXi* @create 2021-07-31 13:15*/
public class LDPepperPizza extends Pizza{@Overridepublic void prepare() {setName("伦敦胡椒披萨");System.out.println("伦敦胡椒披萨 准备原材料");}
}

2.3.2.3 订购披萨父类

package factory.factoryMethod.pizzastore.order;import factory.factoryMethod.pizzastore.pizza.Pizza;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;/*** @author LongXi* @create 2021-07-31 8:55*/
public abstract class OrderPizza {//定义一个抽象方法,cteatePizzaabstract Pizza cteatePizza (String orderType);public OrderPizza() {Pizza pizza = null;String orderType = null;//订购披萨类型do {orderType = getType();//抽象方法,由工厂子类完成pizza = this.cteatePizza(orderType);//输出披萨制作过程pizza.prepare();pizza.bake();pizza.cut();pizza.box();}while(true);}//加一个方法,可以获取客户希望订购的披萨种类private String getType(){try {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));System.out.println("请输入要订购的pizza种类:");String str = null;str = br.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}}
}

2.3.2.3 两个实现类

/*** @author LongXi* @create 2021-07-31 13:27*/
public class BJOrderPizza extends OrderPizza{@OverridePizza cteatePizza(String orderType) {Pizza pizza = null;if (orderType.equals("cheese")){pizza = new BJCheesePizza();} else if (orderType.equals("pepper")){pizza = new BJPepperPizza();}return pizza;}
}

/*** @author LongXi* @create 2021-07-31 13:27*/
public class LDOrderPizza extends OrderPizza{@OverridePizza cteatePizza(String orderType) {Pizza pizza = null;if (orderType.equals("cheese")){pizza = new LDCheesePizza();} else if (orderType.equals("pepper")){pizza = new LDPepperPizza();}return pizza;}
}

2.3.2.4 披萨商店类,主类

/*** @author LongXi* @create 2021-07-31 13:32*/
public class PizzaStore {public static void main(String[] args) {String local = "BJ";if (local.equals("BJ")){// 创建北京口味的各种pizzanew BJOrderPizza();}else {//创建伦敦口味的各种pizzanew LDOrderPizza();}}
}

2.3.2.5 运行结果

请输入要订购的pizza种类:
pepper
北京胡椒披萨 准备原材料
北京胡椒披萨 baking;
北京胡椒披萨 cutting;
北京胡椒披萨 boxing;
请输入要订购的pizza种类:
cheese
北京奶酪披萨 准备原材料
北京奶酪披萨 baking;
北京奶酪披萨 cutting;
北京奶酪披萨 boxing;
请输入要订购的pizza种类:

3. 抽象工厂模式

3.1 什么是抽象工厂模式

  1. 抽象工厂模式:定义了一个interface用于创建相关或有依赖的对象簇,而无需指明具体的类
  2. 抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合
  3. 从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)
  4. 将工厂抽象成两次,AbsFactors(抽象工厂)和具体实现的工厂子类。程序与可以根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。
    TIPS:

3.2 类图

3.3 代码实现

3.3.1 披萨类

package factory.factoryMethod.pizzastore.pizza;/*** @author LongXi* @create 2021-07-31 8:47*/
//将Pizza做成抽象类
public abstract class Pizza {//名字protected String name;//准备原材料,不同的披萨不一样,因此我们做成抽象方法public abstract void prepare();//烘烤public void bake(){System.out.println(name + " baking;");}public void cut(){System.out.println(name + " cutting;");}public void box(){System.out.println(name + " boxing;");}public void setName(String name){this.name = name;}}

3.3.2 4个实现类

/*** @author LongXi* @create 2021-07-31 13:15*/
public class BJCheesePizza extends Pizza{@Overridepublic void prepare() {setName("北京奶酪披萨");System.out.println("北京奶酪披萨 准备原材料");}
}
/*** @author LongXi* @create 2021-07-31 13:15*/
public class BJPepperPizza extends Pizza{@Overridepublic void prepare() {setName("北京胡椒披萨");System.out.println("北京胡椒披萨 准备原材料");}
}
/*** @author LongXi* @create 2021-07-31 13:15*/
public class LDCheesePizza extends Pizza{@Overridepublic void prepare() {setName("伦敦奶酪披萨");System.out.println("伦敦奶酪披萨 准备原材料");}
}
/*** @author LongXi* @create 2021-07-31 13:15*/
public class LDPepperPizza extends Pizza{@Overridepublic void prepare() {setName("伦敦胡椒披萨");System.out.println("伦敦胡椒披萨 准备原材料");}
}

3.3.3 抽象工厂接口

/*** @author LongXi* @create 2021-07-31 14:21*/
//一个抽象工厂模式的抽象层(接口)
public interface AbsFactory {//让下面的工厂子类来具体实现public Pizza cteatePizza (String orderType);
}

3.3.4 两个重新工厂的实现类

/*** @author LongXi* @create 2021-07-31 14:23*/
//这是一个工厂子类
public class BJFactory implements AbsFactory{@Overridepublic Pizza cteatePizza(String orderType) {System.out.println("使用的抽象工厂模式");Pizza pizza = null;if (orderType.equals("cheese")){pizza = new BJCheesePizza();} else if (orderType.equals("pepper")){pizza = new BJPepperPizza();}return pizza;}
}
/*** @author LongXi* @create 2021-07-31 14:23*/
//这是一个工厂子类
public class LDFactory implements AbsFactory{@Overridepublic Pizza cteatePizza(String orderType) {System.out.println("使用的抽象工厂模式");Pizza pizza = null;if (orderType.equals("cheese")){pizza = new LDCheesePizza();} else if (orderType.equals("pepper")){pizza = new LDPepperPizza();}return pizza;}
}

3.3.5 订购披萨类

/*** @author LongXi* @create 2021-07-31 14:27*/
public class OrderPizza {public OrderPizza(AbsFactory absFactory){setFactory(absFactory);}AbsFactory factory;private void setFactory(AbsFactory factory){Pizza pizza = null;String orderType = "";this.factory = factory;do{orderType = getType();pizza = this.factory.cteatePizza(orderType);if (pizza != null){pizza.prepare();pizza.bake();pizza.cut();pizza.box();}else {System.out.println("订购失败");break;}}while(true);}//加一个方法,可以获取客户希望订购的披萨种类private String getType(){try {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));System.out.println("请输入要订购的pizza种类:");String str = null;str = br.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}}
}

3.3.6 披萨商店类

/*** @author LongXi* @create 2021-07-31 14:35*/
public class PizzaStore {public static void main(String[] args) {new OrderPizza(new BJFactory());new OrderPizza(new LDFactory());}
}

3.3.7 运行结果

请输入要订购的pizza种类:
cheese
使用的抽象工厂模式
北京奶酪披萨 准备原材料
北京奶酪披萨 baking;
北京奶酪披萨 cutting;
北京奶酪披萨 boxing;
请输入要订购的pizza种类:
pepper
使用的抽象工厂模式
北京胡椒披萨 准备原材料
北京胡椒披萨 baking;
北京胡椒披萨 cutting;
北京胡椒披萨 boxing;
请输入要订购的pizza种类:
chian
使用的抽象工厂模式
订购失败

4. 工厂模式JDK里的使用

日期类:Calendar

/*** @author LongXi* @create 2021-07-31 14:47*/
public class TestCalendar {public static void main(String[] args) {Calendar calendar = Calendar.getInstance();System.out.println(calendar.get(Calendar.YEAR));}
}

DEBUG看核心代码:

    public static Calendar getInstance(){return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));}
    private static Calendar createCalendar(TimeZone zone,Locale aLocale){CalendarProvider provider =LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale).getCalendarProvider();if (provider != null) {try {return provider.getInstance(zone, aLocale);} catch (IllegalArgumentException iae) {// fall back to the default instantiation}}Calendar cal = null;if (aLocale.hasExtensions()) {String caltype = aLocale.getUnicodeLocaleType("ca");if (caltype != null) {switch (caltype) {case "buddhist":cal = new BuddhistCalendar(zone, aLocale);break;case "japanese":cal = new JapaneseImperialCalendar(zone, aLocale);break;case "gregory":cal = new GregorianCalendar(zone, aLocale);break;}}}if (cal == null) {// If no known calendar type is explicitly specified,// perform the traditional way to create a Calendar:// create a BuddhistCalendar for th_TH locale,// a JapaneseImperialCalendar for ja_JP_JP locale, or// a GregorianCalendar for any other locales.// NOTE: The language, country and variant strings are interned.if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {cal = new BuddhistCalendar(zone, aLocale);} else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja"&& aLocale.getCountry() == "JP") {cal = new JapaneseImperialCalendar(zone, aLocale);} else {cal = new GregorianCalendar(zone, aLocale);}}return cal;}

5. 工厂模式小结

  1. 工厂模式的意义
    将实例化对象的代码提取出来,放到一个类中,统一管理和维护,达到和主项目的依赖关系的解耦。从而提高项目的扩展和维护性。
  2. 三种工厂模式
  3. 设计模式的依赖抽象原则
  • 创建对象实例,不要直接new类,而是把这个new类的动作放到一个工厂的方法中,并返回。有的书上说,变量不要直接持有具体类的引用。
  • 不要让类继承具体类,而是继承抽象类或者是实现interface(接口)
  • 不要覆盖基类中已经实现的方法。

23种设计模式之简单工厂模式,工厂方法模式,抽象工厂模式详解相关推荐

  1. 23种设计模式的简单介绍

    文章目录 23种设计模式 概要 0.简单工厂设计模式 多方法简单工厂 静态方法简单工厂 创造型 单例模式(**Singleton**) 懒汉模式:(以时间换空间) 饿汉模式 (以空间换时间) 工厂方法 ...

  2. 23种设计模式及简单代码

    1. 概述 随着做项目增多不可避免地接触到了设计模式,现在各大文档中呈现的设计模式总共有23种,实际上使用中的肯定比23种多,为了让自己深刻理解设计模式,本博决定自己手写这些设计模式,便于在项目中灵活 ...

  3. 23种设计模式之-----简单工厂(静态工厂)模式(SimpleFactory Pattern)

    这里引用 https://www.kailing.pub/PdfReader/web/viewer.html?file=24DesignPattern 讲解设计模式一文中的例子. 这个例子很形象而且通 ...

  4. 23种设计模式之简单工厂

    简单工厂模式描述的是,通过类的继承关系,父类(工厂类)与子类(产品类),调用父类中的方法,实际干活儿的是子类中的方法:封装需求的不确定性,做出通用的编程,下面以常用的计算器为例: 最容易想到的写法是: ...

  5. java七大设计原则,23种设计模式

    点击查看七大设计原则,23种设计模式 其中 简单工厂.工厂方法.抽象工厂 三种工厂模式中的工厂类的作用基本都是:根据传入的参数创建对应的对象,如果创建的种类太多,那么 简单工厂要写很多 if - el ...

  6. 神了!有人用一个项目把23种设计模式与六大原则融会贯通了

    前言 设计模式分为三类,创建型,结构型和行为型.创建型比较好理解,它抽象了实例化过程,将系统与实例的创建解耦.实例由专门的工厂来创建,从而使系统针对实例的抽象接口编程,不依赖任何具体的实现.结构型和行 ...

  7. Java内功修炼 - 23种设计模式

    一个设计模式的出现一定有它特殊的价值 前段时间二刷Java设计模式 对于设计模式来说,这个东西是始终不变的,所以我把这方面知识归纳为Java内功. 一个技术超牛的程序员,也就和修仙类小说男主角一样.不 ...

  8. PHP 完整实战23种设计模式

    PHP实战创建型模式 单例模式 工厂模式 抽象工厂模式 原型模式 建造者模式 PHP实战结构型模式 桥接模式 享元模式 外观模式 适配器模式 装饰器模式 组合模式 代理模式 过滤器模式 PHP实战行为 ...

  9. 三句话巧记 23 种设计模式

    大家都知道 23 种设计模式,其中又可以分成三类,创建型模式,结构型模式,行为型模式.但是总是在实际应用中忘记了,当具体看到一些代码的时候也想不起来具体对应的是哪种设计模式,对经常重构的代码人员来说是 ...

最新文章

  1. cloning java_深入浅出Java中的clone克隆方法,写得太棒了!
  2. 共享服务器设置权限修改,共享服务器权限设置
  3. 探索 MongoDB--转
  4. Spring Cloud生态的配置服务器最全对比贴
  5. norminv函数是什么matlab,norminv函数的用法,表示的是什么意思
  6. LeetCode 886. 可能的二分法(着色DFS/BFS/拓展并查集)
  7. 不使用 Cookie 的“Cookie”技术
  8. 集合 (一) ----- 集合的基本概念与Collection集合详解
  9. Vue-CoreVideoPlayer 一款基于 vue.js 的轻量级、优秀的视频播放器组件
  10. QLabel 添加下划线 删除线
  11. 可编程控制器PLC概述
  12. Python常见低级错误/拼写错误
  13. ftp服务器文件访问路径,ftp服务器访问路径格式
  14. UVA 10451 Ancient Village Sports UVA 11909 Soya Milk UVA 11152 Colourful Flowers
  15. 移动硬盘的格式化——兼容Mac和Windows
  16. 微信功能升级:低调开卖全球上网卡 得罪群主进不了群
  17. 让逆向工程师们头疼的代码混淆,就像永远也走不出的“浪浪山”
  18. 计算机组成原理实验二 存储器实验
  19. 「Python」Mac下pip出现command not found和Could not find a version that satisfies the requirement ...解决方式
  20. Ubuntu下基于Wine环境安装Visio2007

热门文章

  1. 二级mysql教程下载_全国计算机等级考试教程:二级MySQL数据库程序设计
  2. linux监控指定用户操作,Linux 用户行为轨迹监控
  3. 如何禁止chrome浏览器http自动转成https 【转】
  4. linux之expect
  5. 微信小程序开发-微信登陆流程
  6. 【Windows系统】-- 远程桌面时,WIN键被锁定
  7. WordPress程序伪静态规则(Nginx/Apache)及二级目录规则
  8. .Net开发笔记(十四) 基于“泵”的UDP通信(接上篇)
  9. SQL SERVER的字段类型说明
  10. 一些常用的辅助代码 (网络收藏)