Lihat keperluan khusus
Lihat projek piza: untuk memudahkan pengembangan jenis piza dan kemudahan penyelenggaraan
1) Terdapat banyak jenis piza (seperti GreekPizz, CheesePizz, dll.)
2) Pembuatan pizza termasuk menyediakan, membakar, memotong, kotak
3) Lengkapkan fungsi Pesanan kedai pizza.
package com.example.demo.simplefactory.pizzastore.pizza; /** * 将Pizza 类做成抽象 * @author Administrator * */ 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; } } package com.example.demo.simplefactory.pizzastore.pizza; public class GreekPizza extends Pizza{ @Override public void prepare() { System.out.println(" 给希腊披萨 准备原材料"); } } package com.example.demo.simplefactory.pizzastore.pizza; public class CheesePizza extends Pizza{ @Override public void prepare() { System.out.println(" 给制作奶酪披萨,准备原材料"); } } package com.example.demo.simplefactory.pizzastore.order; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import com.example.demo.simplefactory.pizzastore.pizza.CheesePizza; import com.example.demo.simplefactory.pizzastore.pizza.GreekPizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; 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 制作过程 pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } while (true); } /** * 写一个方法,可以获取客户希望订购的披萨种类 * @return */ private String getType() { try { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); System.out.println("input pizza type : "); String string = bufferedReader.readLine(); return string; } catch(IOException e) { e.printStackTrace(); return ""; } } } package com.example.demo.simplefactory.pizzastore.order; /** * 相当于一个客户端,发出订购 * @author Administrator * */ public class PizzaStore { public static void main(String[] args) { new OrderPizza(); } }
Kebaikan dan keburukan kaedah tradisional:
1) Kelebihannya ialah ia lebih mudah difahami dan mudah dikendalikan.
2) Kelemahannya ialah ia melanggar prinsip OCP corak reka bentuk, yang terbuka kepada sambungan dan tertutup kepada pengubahsuaian. Iaitu, apabila kita menambah fungsi baru pada kelas, cuba untuk tidak mengubah suai kod, atau mengubah suai kod sesedikit mungkin.
3) Sebagai contoh, jika kita ingin menambah jenis pizza baharu, kita perlu mengubah suainya seperti berikut.
package com.example.demo.simplefactory.pizzastore.pizza; public class PepperPizza extends Pizza{ @Override public void prepare() { System.out.println(" 给胡椒披萨准备原材料 "); } } package com.example.demo.simplefactory.pizzastore.order; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import com.example.demo.simplefactory.pizzastore.pizza.CheesePizza; import com.example.demo.simplefactory.pizzastore.pizza.GreekPizza; import com.example.demo.simplefactory.pizzastore.pizza.PepperPizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; 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 制作过程 pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } while (true); } /** * 写一个方法,可以获取客户希望订购的披萨种类 * @return */ private String getType() { try { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); System.out.println("input pizza type : "); String string = bufferedReader.readLine(); return string; } catch(IOException e) { e.printStackTrace(); return ""; } } }
4) Analisis idea yang dipertingkatkan
Analisis: Boleh diterima untuk mengubah suai kod, tetapi jika kita juga mempunyai kod untuk mencipta Pizza di tempat lain, ini bermakna ia juga memerlukan untuk diubah suai, dan Selalunya terdapat beberapa tempat dalam kod untuk membuat Pizza.
Idea: Merangkum penciptaan objek Pizza ke dalam kelas, supaya apabila kita mempunyai jenis pizza baharu, kita hanya perlu mengubah suai kelas dan kod lain yang mencipta objek Pizza tidak perlu diubah suai
Pengenalan asas
1) Corak kilang yang ringkas ialah corak ciptaan dan sejenis corak kilang. Corak kilang ringkas menggunakan objek kilang untuk menentukan contoh kelas produk yang hendak dibuat. Corak kilang ringkas ialah corak paling ringkas dan praktikal dalam keluarga corak kilang
2) Corak kilang ringkas: mentakrifkan kelas yang mencipta objek, dan kelas ini merangkum garisan (kod) objek instantiating .
3) Dalam pembangunan perisian, apabila kita mencipta sejumlah besar objek dari jenis, jenis atau kelompok tertentu, kita akan menggunakan corak kilang.
package com.example.demo.simplefactory.pizzastore.order; import com.example.demo.simplefactory.pizzastore.pizza.CheesePizza; import com.example.demo.simplefactory.pizzastore.pizza.GreekPizza; import com.example.demo.simplefactory.pizzastore.pizza.PepperPizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; /** * 简单工厂类 * @author Administrator * */ public class SimpleFactory { 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; } } package com.example.demo.simplefactory.pizzastore.order; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import com.example.demo.simplefactory.pizzastore.pizza.CheesePizza; import com.example.demo.simplefactory.pizzastore.pizza.GreekPizza; import com.example.demo.simplefactory.pizzastore.pizza.PepperPizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; 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 制作过程 pizza.prepare(); * pizza.bake(); pizza.cut(); pizza.box(); } while (true); } */ /** * 构造器 * @param simpleFactory */ public OrderPizza(SimpleFactory simpleFactory) { setFactory(simpleFactory); } /** * 定义一个简单工厂对象 */ private SimpleFactory simpleFactory; private Pizza pizza = null; private void setFactory(SimpleFactory simpleFactory) { // 用户输入的 String orderTypeString = ""; // 设置简单工厂对象 this.simpleFactory = simpleFactory; do { orderTypeString = getType(); pizza = this.simpleFactory.createPizza(orderTypeString); // 输出pizza // 订购成功 if (pizza != null) { pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } else { System.out.println(" 订购披萨失败 "); break; } } while (true); } /** * 写一个方法,可以获取客户希望订购的披萨种类 * @return */ private String getType() { try { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); System.out.println("input pizza type : "); String string = bufferedReader.readLine(); return string; } catch(IOException e) { e.printStackTrace(); return ""; } } } package com.example.demo.simplefactory.pizzastore.order; /** * 相当于一个客户端,发出订购 * @author Administrator * */ public class PizzaStore { public static void main(String[] args) { //new OrderPizza(); // 使用简单工厂模式 new OrderPizza(new SimpleFactory()); System.out.println("~~退出程序~~"); } }
Lihat keperluan baharu
Keperluan baharu untuk projek pizza: Apabila pelanggan memesan pizza , Anda boleh memesan pelbagai perisa piza, seperti piza keju Beijing, piza lada Beijing atau piza keju London dan piza lada London.
Idea 1
Gunakan corak kilang ringkas untuk mencipta kelas kilang ringkas yang berbeza, seperti BJPizzaSimpleFactory, LDPizzaSimpleFactory, dll. Daripada kes semasa, ia adalah juga Ya, tetapi mengambil kira skala projek dan kebolehselenggaraan serta kebolehskalaan perisian, ia tidak begitu baik
Idea 2
Gunakan kilang Corak kaedah
Pengenalan Corak Kaedah Kilang
Pelan Reka Bentuk Corak Kaedah Kilang: Abstrak fungsi instantiasi projek pizza ke dalam kaedah abstrak untuk memesan makanan dalam perisa berbeza Dilaksanakan secara khusus dalam subkelas.
Corak kaedah kilang: mentakrifkan kaedah abstrak untuk mencipta objek, dan subkelas menentukan kelas untuk dijadikan instantiated. Corak Kaedah Kilang menangguhkan instantiasi objek kepada subkelas .
package com.example.demo.factorymethod.pizzastore.order; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; import com.fasterxml.jackson.databind.deser.ValueInstantiator.Gettable; public abstract class OrderPizza { public OrderPizza() { Pizza pizza = null; // 订购披萨的类型 String orderType; do { orderType = getType(); createPizza(orderType); // 输出Pizza 制作过程 pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } while (true); } /** * 定义一个抽象方法,createPizza,让各个工厂子类自己实现 * @param orderType * @return */ abstract Pizza createPizza(String orderType); /** * 写一个方法,可以获取客户希望订购的披萨种类 * @return */ private String getType() { try { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); System.out.println("input pizza type : "); String string = bufferedReader.readLine(); return string; } catch(IOException e) { e.printStackTrace(); return ""; } } } package com.example.demo.factorymethod.pizzastore.order; import org.apache.tomcat.util.security.Escape; import com.example.demo.factorymethod.pizzastore.pizza.LDCheesePizza; import com.example.demo.factorymethod.pizzastore.pizza.LDPepperPizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class LDOrderPizza extends OrderPizza{ @Override Pizza createPizza(String orderType) { Pizza pizza = null; if (orderType.equals("cheese")) { pizza = new LDCheesePizza(); } else if (orderType.equals("pepper")) { pizza = new LDPepperPizza(); } return pizza; } } package com.example.demo.factorymethod.pizzastore.order; import com.example.demo.factorymethod.pizzastore.pizza.BJCheesPizza; import com.example.demo.factorymethod.pizzastore.pizza.BJPepperPizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class BJOrderPizza extends OrderPizza{ @Override Pizza createPizza(String orderType) { Pizza pizza = null; if (orderType.equals("cheese")) { pizza = new BJCheesPizza(); } else if (orderType.equals("pepper")) { pizza = new BJPepperPizza(); } return pizza; } } package com.example.demo.factorymethod.pizzastore.pizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class BJCheesPizza extends Pizza{ @Override public void prepare() { setName("北京的奶酪pizza"); System.out.println(" 北京的奶酪pizza 准备原材料 "); } } package com.example.demo.factorymethod.pizzastore.pizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class BJPepperPizza extends Pizza{ @Override public void prepare() { setName(" 北京的胡椒pizza "); System.out.println(" 北京的胡椒pizza 准备原材料 "); } } package com.example.demo.factorymethod.pizzastore.pizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class LDCheesePizza extends Pizza{ @Override public void prepare() { setName(" 伦敦的奶酪pizza "); System.out.println(" 伦敦的奶酪pizza 准备原材料 "); } } package com.example.demo.factorymethod.pizzastore.pizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class LDPepperPizza extends Pizza{ @Override public void prepare() { setName(" 伦敦的胡椒pizza "); System.out.println(" 伦敦的胡椒pizza 准备原材料 "); } } package com.example.demo.factorymethod.pizzastore.order; public class PizzaStore { public static void main(String[] args) { // 创建北京口味的各种Pizza new BJOrderPizza(); } }
Pengenalan Asas
1) Corak Kilang Abstrak: Satu antara muka ditakrifkan untuk mencipta objek berkaitan atau kelompok dengan kebergantungan tanpa menyatakan kelas tertentu
2) Corak kilang abstrak boleh menyepadukan corak kilang ringkas dan corak kaedah kilang
3) Dari perspektif reka bentuk, corak kilang abstrak adalah penambahbaikan (atau abstraksi selanjutnya) daripada corak kilang yang ringkas.
4) Abstrak kilang kepada dua lapisan, AbsFactory (kilang abstrak) dan subkelas kilang yang dilaksanakan konkrit. Pengaturcara boleh menggunakan subkelas kilang yang sepadan berdasarkan jenis objek yang mereka cipta. Ini menjadikan satu kelas kilang ringkas menjadi gugusan kilang, yang lebih kondusif untuk penyelenggaraan dan pengembangan kod.
package com.example.demo.absfactory.pizzastore.order; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; /** * 一个抽象工厂模式的抽象层(接口) * @author Administrator * */ public interface AbsFactory { /** * 让下面的工厂子类来 具体实现 * @param orderType * @return */ Pizza createPizza(String orderType); } package com.example.demo.absfactory.pizzastore.order; import com.example.demo.absfactory.pizzastore.pizza.BJCheesPizza; import com.example.demo.factorymethod.pizzastore.pizza.BJPepperPizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; /** * 这是工厂子类 * @author Administrator * */ public class BJFactory implements AbsFactory{ @Override public Pizza createPizza(String orderType) { System.out.println("~使用的是抽象工厂模式~"); Pizza pizza = null; if (orderType.equals("cheese")) { pizza = new BJCheesPizza(); } else if (orderType.equals("pepper") ) { pizza = new BJPepperPizza(); } return pizza; } } package com.example.demo.absfactory.pizzastore.order; import com.example.demo.absfactory.pizzastore.pizza.LDCheesePizza; import com.example.demo.absfactory.pizzastore.pizza.LDPepperPizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class LDFactory implements AbsFactory{ @Override public Pizza createPizza(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; } } package com.example.demo.absfactory.pizzastore.order; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class OrderPizza { private AbsFactory factory; /** * 构造器 * @param factory */ public OrderPizza(AbsFactory factory) { setFactory(factory); } private void setFactory(AbsFactory factory) { Pizza pizza = null; // 用户输入 String orderTypeString = ""; this.factory = factory; do { orderTypeString = getType(); pizza = factory.createPizza(orderTypeString); if (pizza != null) { pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } else { System.out.println("~订购失败~"); break; } } while (true); } /** * 写一个方法,可以获取客户希望订购的披萨种类 * @return */ private String getType() { try { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); System.out.println("input pizza type : "); String string = bufferedReader.readLine(); return string; } catch(IOException e) { e.printStackTrace(); return ""; } } } package com.example.demo.absfactory.pizzastore.pizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class BJCheesPizza extends Pizza{ @Override public void prepare() { setName("北京的奶酪pizza"); System.out.println(" 北京的奶酪pizza 准备原材料 "); } } package com.example.demo.absfactory.pizzastore.pizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class BJPepperPizza extends Pizza{ @Override public void prepare() { setName(" 北京的胡椒pizza "); System.out.println(" 北京的胡椒pizza 准备原材料 "); } } package com.example.demo.absfactory.pizzastore.pizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class LDCheesePizza extends Pizza{ @Override public void prepare() { setName(" 伦敦的奶酪pizza "); System.out.println(" 伦敦的奶酪pizza 准备原材料 "); } } package com.example.demo.absfactory.pizzastore.pizza; import com.example.demo.simplefactory.pizzastore.pizza.Pizza; public class LDPepperPizza extends Pizza{ @Override public void prepare() { setName(" 伦敦的胡椒pizza "); System.out.println(" 伦敦的胡椒pizza 准备原材料 "); } } package com.example.demo.absfactory.pizzastore.order; public class PizzaStore { public static void main(String[] args) { new OrderPizza(new BJFactory()); } }
Analisis kod sumber mod kilang dalam aplikasi JDK-Kalendar
1) Dalam kelas Kalendar dalam JDK, mod kilang ringkas digunakan
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; }
Atas ialah kandungan terperinci Analisis kod contoh corak kilang Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!