案例分析:设计模式与代码的结构特性
一、什么是软件设计模式
1、概念
软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。
2、作用
使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。
3、分类
软件设计模式一般可分为以下几类:
(2)结构模式
(3)行为模式
(4)并发模式
(5)实时模式
(6)其他:模型—视图—控制器模式
本文选取创建模式中的工厂方法模式展开具体分析。
二、工厂方法模式(Factory Method)
1、简单工厂模式
在正式介绍工厂方法模式之前,我们首先对简单工厂模式做简要介绍,以便帮助我们更好的理解工厂方法模式。
简单工厂模式不属于以上介绍的软件设计模式的分类中,可分为:普通简单工厂、多方法简单工厂和静态方法简单工厂。
适用于大量产品需要创建,并且这些产品具有共同的接口的情况,并且在三种分类中,通常选用静态方法简单工厂。
(1)普通简单工厂
建立一个工厂类,使用该类的同一接口创建实例。
关系图如下所示:
举例说明(以发送邮件和短信的例子):
第一步:创建发送的共同接口
1 public interface Sender { 2 public void Send(); 3 }
第二步:创建实现类
发送邮件的实现类:
1 public class MailSender implements Sender { 2 @Override 3 public void Send() { 4 System.out.println("this is mailsender!"); 5 } 6 }
发送短信的实现类:
1 public class SmsSender implements Sender { 2 3 @Override 4 public void Send() { 5 System.out.println("this is sms sender!"); 6 } 7 }
第三步:建立工厂类
1 public class SendFactory { 2 3 public Sender produce(String type) { 4 if ("mail".equals(type)) { 5 return new MailSender(); 6 } else if ("sms".equals(type)) { 7 return new SmsSender(); 8 } else { 9 System.out.println("请输入正确的类型!"); 10 return null; 11 } 12 } 13 }
测试:
1 public class FactoryTest { 2 3 public static void main(String[] args) { 4 SendFactory factory = new SendFactory(); 5 Sender sender = factory.produce("sms"); 6 sender.Send(); 7 } 8 }
输出结果为:thiis is sms sender!
(2)多方法简单工厂
对普通简单工厂的改进,解决了普通简单工厂中因字符串传递出错而不能正确创建对象的问题。在多方法简单工厂中,提供了多个工厂方法,分别用于创建不同的对象。
关系图如下所示:
(3)静态方法简单工厂
又是对多个方法简单工厂的改进,将多个方法简单工厂中的方法设置为静态(static)的,不需要再创建实例。
2、工厂方法模式
在简单工厂模式中,类的创建完全依赖于工厂类,这就意味着,如果我们因为工作的拓展需要修改程序时,必须去修改工厂类,这种做法违反了软件设计模式中的闭包原则。
解决措施:提出了工厂方法模式,我们创建一个工厂接口和多个工厂实现类,在这种情况下, 需要添加新的功能时只需要添加新的工厂实现类就可以了,不用再对工厂接口做任何的修改,符合软件设计模式的原则。
关系图如下所示:
举例说明(仍然以发送邮件和短信来进行说明):
第一步:创建一个接口类
1 public interface Sender { 2 public void Send(); 3 }
第二步:创建基于接口类的两个实现类
发送邮件的实现类:
1 public class MailSender implements Sender { 2 @Override 3 public void Send() { 4 System.out.println("this is mailsender!"); 5 } 6 }
发送短信的实现类:
1 public class SmsSender implements Sender { 2 3 @Override 4 public void Send() { 5 System.out.println("this is sms sender!"); 6 } 7 }
第三步:增加一个接口
1 public interface Provider { 2 public Sender produce(); 3 }
第四步:创建基于新的接口的两个工厂类
发送邮件的工厂类:
1 public class SendMailFactory implements Provider { 2 3 @Override 4 public Sender produce(){ 5 return new MailSender(); 6 } 7 }
发送短信的工厂类:
1 public class SendSmsFactory implements Provider{ 2 3 @Override 4 public Sender produce() { 5 return new SmsSender(); 6 } 7 }
测试:
1 public class Test { 2 3 public static void main(String[] args) { 4 Provider provider = new SendMailFactory(); 5 Sender sender = provider.produce(); 6 sender.Send(); 7 } 8 }
结果为:this is mail sender!
三、模式分析
1、引入该设计模式后对系统架构和代码结构带来了哪些好处?
工厂方法模式的是定义一个创建产品对象的工厂接口或抽象方法,让子类决定实例化哪一个类。工厂方法是一个类的实例化延迟的其子类。因为每一个具体产品类对应着一个具体的工厂类,故增加具体产品时只需要增加一个具体工厂类.。工厂方法模式是简单工厂模式的进一步抽象和推广,克服了简单工厂的违背开放-封闭原则的缺点,又保持了封装对象创建过程的优点。
2、解释其中用到的多态机制
主要涉及到的是编译时多态,有多个不同的子类继承自相同的一个父类,由子类对象的类型决定具体应该去实例化哪一个类。
3、说明模块抽象封装的方法
抽象:在定义类时,将一类事务的公有属性和行为进行提取,形成一个固定的模型。如上文中的Sender类。
封装:把抽象之后的数据和对数据的操作封装在一起,数据保存在内部,只有某个被允许访问的行为和操作才能对数据进行更改。
4、分析各个模块的内聚度和模块之间的耦合度
内聚度:标志着一个模块内部各成分彼此结合的紧密程度。此处工厂实现类中的各元素共同完成一个功能,基本上不涉及到其他模块的功能,内聚度较高。
耦合度:标志着各模块之间关联程度的多少。此处的工厂实现类依赖于工厂接口,但是工厂接口不涉及到实现,因此模块间的耦合度较低。