Chinaunix首页 | 论坛 | 博客
  • 博客访问: 180049
  • 博文数量: 19
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1182
  • 用 户 组: 普通用户
  • 注册时间: 2013-02-20 23:47
个人简介

如果人生是一条隐含马尔科夫模型,那维特比算法告诉我已经偏离最优路线了,但如果起点是现在呢?

文章分类

全部博文(19)

文章存档

2020年(2)

2014年(3)

2013年(14)

分类: 架构设计与优化

2014-01-05 17:04:14

    如果你是像作者一样参加工作一年有多了,看完此文后,请立即去拿回属于你们的财富——设计模式吧

    事情经过是这样的,面试官问到什么是抽象工厂设计模式,我们先来看看什么是简单工厂模式

    其中Factory代码是这样的


点击(此处)折叠或打开

  1. /**
  2. * Created by ye on 14-1-5.
  3. */
  4. public class Factory {
  5.     public EProductApple produce(String name) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
  6.         EProductApple apple = (EProductApple) Class.forName("com.qunar.flight.flagship.cpa.pattern." + name).newInstance();
  7.         return apple;
  8.     }
  9. }

    Class.forName,用过spring类似框架的再熟悉不过了,这里用来演示简单工厂创建一个对象;其实简单工厂就算刚学会java的同学也好理解:要什么、只用提供一个简简单单的字符串或者别的信息,就能返回一个复杂的对象,但是抽象工厂呢?作者当年着实没能理解,反复看了好几遍也没能,最多背下来,可是设计模式不比算法,背下来什么用都没有(其实有些算法背下来也是无用的)顺着上面这个造苹果的例子,我们再造个三星,就能“很好”的理解抽象工厂了。

    抽象工厂,5个字解释就是————工厂的工厂:因为三星也有对应的手持通讯设备以及平板娱乐设备,我们做一个抽象EProductCommunicationEProductEntertainment,且工厂也抽出一个通用工厂来,专门生产苹果工厂or三星工厂,类图如下


点击(此处)折叠或打开

  1. public interface SuperFactory {
  2.     public EProductCommunication produceMobile();
  3.     public EProductEntertainment produceTablet();
  4. }

苹果工厂的实现

点击(此处)折叠或打开

  1. public class AppleFactory implements SuperFactory {

  2.     public EProductCommunication produceMobile() {
  3.         return new IPhone();
  4.     }

  5.     public EProductEntertainment produceTablet() {
  6.         return new IPad();
  7.     }
  8. }

苹果产品对两个接口的实现:

点击(此处)折叠或打开

  1. public class IPhone implements EProductCommunication {
  2.     public void makeCall(){
  3.         System.out.println("iPhone 打电话...");
  4.     }
  5. }

  6. public class IPad implements EProductEntertainment{
  7.     public void playGame(){
  8.         System.out.println("iPad 打游戏...");
  9.     }
  10. }

类图如下

大家可能有注意到,为什么我对产品种类做的抽象,而不是品牌,如果能敏锐的发现这一点,你离使用抽象工厂最高境界很近了(*^__^*)

没错,我可以对品牌做抽象,做成如下:


点击(此处)折叠或打开

  1. public interface SuperFactory {
  2.     public EProductApple produceApple();
  3.     public EProductSamsung produceSamsung();
  4. }

  5. public class MobileFactory implements SuperFactory {

  6.     public EProductApple produceApple() {
  7.         return new IPhone();
  8.     }

  9.     public EProductSamsung produceSamsung() {
  10.         return new IPad();
  11.     }
  12. }

    EProductApple下面有iPhoneiPad两个实现,大家对比一下,除了做了一下类似线代里面的转置,以品牌为导向的抽象工厂与以种类为导向的抽象工厂完全相似,但是他们对应的业务场景完全相反,为什么这么说,假如乔布斯醒来了,搞了一种叫iWatch的产品,戴在头上,总之很牛逼的样子,三星等周围厂商纷纷效仿,请问上面哪种抽象工厂改动最少?

    以产品为导向的:修改SuperFactory增加一个新的方法

    

点击(此处)折叠或打开

  1. public EProductNiubility produceNiubility();

并且实现了SuperFactory的类也得跟着修改,并增加一种新的intefaceEProductNiubility,下面有各大厂商的实现,苹果的取名iWatch,三星的取名iSee

    以品牌为导向的:增加SuperFactory的一种实现—— NiubilityFactory,除此之外,无需修改任何既有类,所有操作都是扩展

我们对系统的修改要讲究开闭原则,即对扩展开放,对修改关闭;因此,对于乔布斯有可能醒来这种业务场景,你需要选择后者这种以品牌为导向的抽象工厂,因为它的修改最少,然而乔布斯不可能醒过来,再崛起一家像苹果三星一样的品牌也不容易,我们在设计抽象工厂一定要具体问题具体分析,选择最合适你的业务场景的抽象工厂
    如果是在一年前,作者是不可能理解抽象工厂的博大精深的,但为什么网上随便搜了一篇文章后能快速理解呢,这主要是因为这一年搬了不少砖,特别处理重复度比较高的业务,因此对于设计模式这种专业级代码精简美化的手法有种莫名的渴望,而刚参加工作时并没有多少开发经验,设计模式看了一遍又一遍,除了几个比较小白一点的设计模式(单例模式),皆如对牛弹琴,因此如果你也像作者这样,也可以照着23种常用设计模式去review一下过去一年设计过的系统,相信会有新的发现

阅读(5008) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~