一、小案例分析1、功能需求: 实现一个发送信息的功能,要便于扩展与维护。 2、小菜鸡去实现:(1)定义一个发送工具的父类(接口),并将各种发送工具作为子类(实现类)。 package creative.pattern.factory.noFactory; import java.util.Scanner; /** * 测试类 * */ public class Demo { public static void main(String[] args) { new SendMessage();// 实例化一个选择发送工具的类 } } /** * 定义一个发送工具的接口 * */ interface Sender { void sendMessage(); } /** * 定义一个短信发送工具,实现接口,重写方法 * */ class ShortMessageSender implements Sender { @Override public void sendMessage() { System.out.println("发送短信"); } } /** * 定义一个微信发送工具,实现接口,重写方法 * */ class WeChatSender implements Sender { @Override public void sendMessage() { System.out.println("发送微信"); } } /** * 定义一个邮件发送工具,实现接口,重写方法 * */ class MailSender implements Sender { @Override public void sendMessage() { System.out.println("发送邮件"); } } /** * 定义一个选择发送工具的类 */ class SendMessage { /** * 用于获取需要发送信息工具 */ public Sender getSenderType() { System.out.println("输入发送工具的类型(1-3):"); System.out.println("1:短信"); System.out.println("2:微信"); System.out.println("3:邮件"); Scanner scanner = new Scanner(System.in); String senderType = scanner.nextLine(); if ("1".equals(senderType)) { return new ShortMessageSender(); } else if ("2".equals(senderType)) { return new WeChatSender(); } else if ("3".equals(senderType)) { return new MailSender(); } else { return null; } } public SendMessage() { do { Sender sender = getSenderType();// 选择发送信息的工具 if (sender == null) { System.out.println("欢迎下次使用"); break; } else { sender.sendMessage(); } } while (true); } } (4)代码分析:
二、简单工厂模式(SimpleFactory)1、什么是简单工厂模式:简单工厂模式属于创建型模式,不属于常见的23种常见模式。简单的讲 简单工厂模式是由一个工厂对象决定创建出哪一类产品的实例。 2、使用:(1)简单工厂模式,定义了一个创建对象的类,然后由这个类来封装实例化对象的操作。 3、使用简单工厂模式实现:(1)定义一个发送工具的父类(接口),并将各种发送工具作为子类(实现类)。 package creative.pattern.factory.simpleFactory; import java.util.Scanner; /** * 测试类 * */ public class SimpleFactoryDemo { public static void main(String[] args) { new SendMessage(); } } /** * 定义一个发送工具的接口 * */ interface Sender { void sendMessage(); } /** * 定义一个短信发送工具,实现接口,重写方法 * */ class ShortMessageSender implements Sender { @Override public void sendMessage() { System.out.println("发送短信"); } } /** * 定义一个微信发送工具,实现接口,重写方法 * */ class WeChatSender implements Sender { @Override public void sendMessage() { System.out.println("发送微信"); } } /** * 定义一个邮件发送工具,实现接口,重写方法 * */ class MailSender implements Sender { @Override public void sendMessage() { System.out.println("发送邮件"); } } /** * 使用简单工厂模式,管理需要生产的对象 * */ class SimpleFactory { /** * 用于获取需要发送信息工具 */ public static Sender createSender() { System.out.println("输入发送工具的类型(1-3):"); System.out.println("1:短信"); System.out.println("2:微信"); System.out.println("3:邮件"); Scanner scanner = new Scanner(System.in); String senderType = scanner.nextLine(); if ("1".equals(senderType)) { return new ShortMessageSender(); } else if ("2".equals(senderType)) { return new WeChatSender(); } else if ("3".equals(senderType)) { return new MailSender(); } else { return null; } } } /** * 定义一个选择发送工具的类 */ class SendMessage { public SendMessage() { do { Sender sender = SimpleFactory.createSender();// 选择发送信息的工具 if (sender == null) { System.out.println("欢迎下次使用"); break; } else { sender.sendMessage(); } } while (true); } } (4)代码分析:
4、使用静态工厂模式实现(常用形式): 将上例的SimpleFactory 中public Sender createSender()改为 public static Sender createSender()。 public static Sender createSender() { System.out.println("输入发送工具的类型(1-3):"); System.out.println("1:短信"); System.out.println("2:微信"); System.out.println("3:邮件"); Scanner scanner = new Scanner(System.in); String senderType = scanner.nextLine(); if ("1".equals(senderType)) { return new ShortMessageSender(); } else if ("2".equals(senderType)) { return new WeChatSender(); } else if ("3".equals(senderType)) { return new MailSender(); } else { return null; } } 三、工厂方法模式1、什么是工厂方法模式:在工厂内部定义一个创建对象的抽象方法,由子类去确定要实例化的对象。简单的讲 工厂方法模式将对象实例化的操作推迟到子类去实现。可以看做抽象工厂模式的一个常见类型。 2、使用工厂模式实现:(1)定义一个发送工具的父类(接口),并将各种发送工具作为子类(实现类)。 package creative.pattern.factory.factoryMethod; import java.util.Scanner; /** * 工厂方法模式测试类 * */ public class factoryMethodDemo { public static void main(String[] args) { new SendMessage(); } } /** * 定义一个发送工具的接口 * */ interface Sender { void sendMessage(); } /** * 定义一个短信发送工具,实现接口,重写方法 * */ class ShortMessageSender implements Sender { @Override public void sendMessage() { System.out.println("发送短信"); } } /** * 定义一个微信发送工具,实现接口,重写方法 * */ class WeChatSender implements Sender { @Override public void sendMessage() { System.out.println("发送微信"); } } /** * 定义一个邮件发送工具,实现接口,重写方法 * */ class MailSender implements Sender { @Override public void sendMessage() { System.out.println("发送邮件"); } } /** * 使用工厂方法模式,让子类去创建对象 * */ interface FactoryMethod { Sender sendMessage(); } /** * 短信工厂类,实现工厂方法类并重写相关方法 * */ class ShortMessageFactory implements FactoryMethod { @Override public Sender sendMessage() { return new ShortMessageSender(); } } /** * 微信工厂类,实现工厂方法类并重写相关方法 * */ class WeChatFactory implements FactoryMethod { @Override public Sender sendMessage() { return new WeChatSender(); } } /** * 邮件工厂类,实现工厂方法类并重写相关方法 * */ class MailFactory implements FactoryMethod { @Override public Sender sendMessage() { return new MailSender(); } } /** * 定义一个选择发送工具的类 */ class SendMessage { public SendMessage() { do { System.out.println("输入发送工具的类型(1-3):"); System.out.println("1:短信"); System.out.println("2:微信"); System.out.println("3:邮件"); Scanner scanner = new Scanner(System.in); String senderType = scanner.nextLine(); if ("1".equals(senderType)) { FactoryMethod factoryMethod = new ShortMessageFactory(); Sender sender = factoryMethod.sendMessage();// 选择发送短信 sender.sendMessage(); } else if ("2".equals(senderType)) { FactoryMethod factoryMethod = new WeChatFactory(); Sender sender = factoryMethod.sendMessage();// 选择发送微信 sender.sendMessage(); } else if ("3".equals(senderType)) { FactoryMethod factoryMethod = new MailFactory(); Sender sender = factoryMethod.sendMessage();// 选择发送邮件 sender.sendMessage(); } else { System.out.println("欢迎下次使用"); break; } } while (true); } } (5)代码分析:
四、抽象工厂模式1、什么是抽象工厂模式 为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。 2、抽象工厂模式与工厂方法模式的区别(1)抽象工厂模式是工厂方法模式的升级版,其针对的是多个产品等级结构,即抽象工厂模式所提供的产品是衍生自不同的接口或抽象类。 下图为抽象工厂模式: 3、举例: 在之前案例的基础上,增加一个功能,微信、短信均可以图片。 package creative.pattern.factory.absFactory; /** * 抽象工厂模式测试类 * */ public class AbsFactoryDemo { public static void main(String[] args) { AbsFactory absFactory = new WeChatFactory(); absFactory.getSender().sendMessage(); absFactory.getSender2().sendMessage(); ((WeChatSender2) absFactory.getSender2()).sendPicture(); AbsFactory absFactory2 = new ShortMessageFactory(); absFactory2.getSender().sendMessage(); absFactory2.getSender2().sendMessage(); ((ShortMessageSender2) absFactory2.getSender2()).sendPicture(); } } /** * 定义一个发送工具的接口 * */ interface Sender { void sendMessage(); } /** * 定义一个微信发送工具,实现接口,重写方法 * */ class WeChatSender implements Sender { @Override public void sendMessage() { System.out.println("使用微信,发送短信"); } } /** * 定义一个微信发送工具,实现接口,重写方法,并新增自己的方法 * */ class WeChatSender2 implements Sender { @Override public void sendMessage() { System.out.println("使用微信,发送短信"); } public void sendPicture() { System.out.println("使用微信,发送图片"); } } /** * 定义一个短信发送工具,实现接口,重写方法 * */ class ShortMessageSender implements Sender { @Override public void sendMessage() { System.out.println("使用短信,发送短信"); } } /** * 定义一个短信发送工具,实现接口,重写方法,并新增自己的方法 * */ class ShortMessageSender2 implements Sender { @Override public void sendMessage() { System.out.println("使用短信,发送短信"); } public void sendPicture() { System.out.println("使用短信,发送图片"); } } /** * 抽象工厂模式 * */ interface AbsFactory { Sender getSender(); Sender getSender2(); } /** * 工厂子类,实现抽象工厂类,重写相关方法, * */ class WeChatFactory implements AbsFactory { @Override public Sender getSender() { return new WeChatSender(); } @Override public Sender getSender2() { return new WeChatSender2(); } } /** * 工厂子类,实现抽象工厂类,重写相关方法, * */ class ShortMessageFactory implements AbsFactory { @Override public Sender getSender() { return new ShortMessageSender(); } @Override public Sender getSender2() { return new ShortMessageSender2(); } } (5)代码分析: (6)UML图: 五、JDK中工厂模式举例(Calendar)1、部分源码public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar> { /** * Gets a calendar using the default time zone and locale. The * <code>Calendar</code> returned is based on the current time * in the default time zone with the default * {@link Locale.Category#FORMAT FORMAT} locale. * * @return a Calendar. */ 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; } } 2、源码分析Calendar内部采用简单工厂模式进行对象的实例化。其根据不同的逻辑判断条件来选择实例化具体的对象。
六、总结:1、工厂模式的意义:将实例化对象的代码提取出来,放到一个类(工厂类)里面进行维护,使其与主项目解耦,提高程序的维护性与扩展性。 2、传统模式:直接在需要的地方实例化某对象。扩展代码时,需要在使用到的地方进行修改,违反了开闭原则。 3、简单工厂模式: 在需要用到的地方,调用工厂类即可,扩展代码时,修改工厂类即可,也违反了开闭原则。 4、工厂方法模式:使用一个工厂类接口与多个工厂实现类,在不同的工厂实现类中去实例化不同的对象。扩展代码时,定义一个工厂实现类,实现工厂类接口并重写相关方法即可,满足开闭原则。可以理解为抽象工厂模式的一般形式。 5、抽象工厂模式:可以理解为工厂方法模式的升级版,其在一个接口中定义了一个产品族的处理(多个方法),子类实现该接口,并重写相关方法即可,扩展类似于工厂方法模式,满足开闭原则。 |
|
来自: python_lover > 《待分类》