23种设计模式之简单工厂模式,工厂方法模式,抽象工厂模式详解
工厂模式详解
- 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 需求分析
看一个披萨的项目:要便于披萨种类的扩展,要便于维护。
- 披萨的种类很多,比如GreekPizz,CheesePizz等
- 披萨的制作工序有prepare,bake,cut,box
- 完成披萨店订购功能
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 传统方式优缺点分析
- 优点:比较好理解,简单易操作
- 缺点:违反了设计模式的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.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 什么是抽象工厂模式
- 抽象工厂模式:定义了一个interface用于创建相关或有依赖的对象簇,而无需指明具体的类
- 抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合
- 从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)
- 将工厂抽象成两次,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. 工厂模式小结
- 工厂模式的意义
将实例化对象的代码提取出来,放到一个类中,统一管理和维护,达到和主项目的依赖关系的解耦。从而提高项目的扩展和维护性。 - 三种工厂模式
- 设计模式的依赖抽象原则
- 创建对象实例,不要直接new类,而是把这个new类的动作放到一个工厂的方法中,并返回。有的书上说,变量不要直接持有具体类的引用。
- 不要让类继承具体类,而是继承抽象类或者是实现interface(接口)
- 不要覆盖基类中已经实现的方法。
23种设计模式之简单工厂模式,工厂方法模式,抽象工厂模式详解相关推荐
- 23种设计模式的简单介绍
文章目录 23种设计模式 概要 0.简单工厂设计模式 多方法简单工厂 静态方法简单工厂 创造型 单例模式(**Singleton**) 懒汉模式:(以时间换空间) 饿汉模式 (以空间换时间) 工厂方法 ...
- 23种设计模式及简单代码
1. 概述 随着做项目增多不可避免地接触到了设计模式,现在各大文档中呈现的设计模式总共有23种,实际上使用中的肯定比23种多,为了让自己深刻理解设计模式,本博决定自己手写这些设计模式,便于在项目中灵活 ...
- 23种设计模式之-----简单工厂(静态工厂)模式(SimpleFactory Pattern)
这里引用 https://www.kailing.pub/PdfReader/web/viewer.html?file=24DesignPattern 讲解设计模式一文中的例子. 这个例子很形象而且通 ...
- 23种设计模式之简单工厂
简单工厂模式描述的是,通过类的继承关系,父类(工厂类)与子类(产品类),调用父类中的方法,实际干活儿的是子类中的方法:封装需求的不确定性,做出通用的编程,下面以常用的计算器为例: 最容易想到的写法是: ...
- java七大设计原则,23种设计模式
点击查看七大设计原则,23种设计模式 其中 简单工厂.工厂方法.抽象工厂 三种工厂模式中的工厂类的作用基本都是:根据传入的参数创建对应的对象,如果创建的种类太多,那么 简单工厂要写很多 if - el ...
- 神了!有人用一个项目把23种设计模式与六大原则融会贯通了
前言 设计模式分为三类,创建型,结构型和行为型.创建型比较好理解,它抽象了实例化过程,将系统与实例的创建解耦.实例由专门的工厂来创建,从而使系统针对实例的抽象接口编程,不依赖任何具体的实现.结构型和行 ...
- Java内功修炼 - 23种设计模式
一个设计模式的出现一定有它特殊的价值 前段时间二刷Java设计模式 对于设计模式来说,这个东西是始终不变的,所以我把这方面知识归纳为Java内功. 一个技术超牛的程序员,也就和修仙类小说男主角一样.不 ...
- PHP 完整实战23种设计模式
PHP实战创建型模式 单例模式 工厂模式 抽象工厂模式 原型模式 建造者模式 PHP实战结构型模式 桥接模式 享元模式 外观模式 适配器模式 装饰器模式 组合模式 代理模式 过滤器模式 PHP实战行为 ...
- 三句话巧记 23 种设计模式
大家都知道 23 种设计模式,其中又可以分成三类,创建型模式,结构型模式,行为型模式.但是总是在实际应用中忘记了,当具体看到一些代码的时候也想不起来具体对应的是哪种设计模式,对经常重构的代码人员来说是 ...
最新文章
- cloning java_深入浅出Java中的clone克隆方法,写得太棒了!
- 共享服务器设置权限修改,共享服务器权限设置
- 探索 MongoDB--转
- Spring Cloud生态的配置服务器最全对比贴
- norminv函数是什么matlab,norminv函数的用法,表示的是什么意思
- LeetCode 886. 可能的二分法(着色DFS/BFS/拓展并查集)
- 不使用 Cookie 的“Cookie”技术
- 集合 (一) ----- 集合的基本概念与Collection集合详解
- Vue-CoreVideoPlayer 一款基于 vue.js 的轻量级、优秀的视频播放器组件
- QLabel 添加下划线 删除线
- 可编程控制器PLC概述
- Python常见低级错误/拼写错误
- ftp服务器文件访问路径,ftp服务器访问路径格式
- UVA 10451 Ancient Village Sports UVA 11909 Soya Milk UVA 11152 Colourful Flowers
- 移动硬盘的格式化——兼容Mac和Windows
- 微信功能升级:低调开卖全球上网卡 得罪群主进不了群
- 让逆向工程师们头疼的代码混淆,就像永远也走不出的“浪浪山”
- 计算机组成原理实验二 存储器实验
- 「Python」Mac下pip出现command not found和Could not find a version that satisfies the requirement ...解决方式
- Ubuntu下基于Wine环境安装Visio2007
热门文章
- 二级mysql教程下载_全国计算机等级考试教程:二级MySQL数据库程序设计
- linux监控指定用户操作,Linux 用户行为轨迹监控
- 如何禁止chrome浏览器http自动转成https 【转】
- linux之expect
- 微信小程序开发-微信登陆流程
- 【Windows系统】-- 远程桌面时,WIN键被锁定
- WordPress程序伪静态规则(Nginx/Apache)及二级目录规则
- .Net开发笔记(十四) 基于“泵”的UDP通信(接上篇)
- SQL SERVER的字段类型说明
- 一些常用的辅助代码 (网络收藏)