- 浏览: 21919 次
- 性别:
- 来自: 厦门
文章分类
最新评论
(注:代码在最底下的附件)
1.简单工厂
郭大神和盘哥在说好想买ipad,用代码实现一下
不用模式的设计
有何问题?
如果想买的iphone5时怎么办?
得找到所有new IpadProduct改成new IphoneProduct
而且改的是客户端的代码
应用模式的设计
无模式遇到的问题如何解决?
只要在SimpleFactory.getProdcut()换成IphoneProdcut即可
优点
创建对象收拢,扩展性加强了。
扩展时不需要修改客户端代码。
对象创建与使用解耦
缺点
多出一个工厂类
2.工厂方法
应用工厂方法模式的设计
优点
可以在不知道具体产品下实现编程
可以在不改变业务代码上很容易扩展出一个新的产品
缺点
多出几个具体工厂类
3.抽象工厂
考虑一下生产ipad和iphone的一个程序
工厂模式的设计有何问题?
工厂模式的设计有何问题?
客户端想只买一家公司的产品,客户端需要了解每种类型是出自哪一家公司?
港版ipad与iphone是出自同一家公司,美版ipad与iphone也是出自同一样公司,对于采购时
它只要报一下要什么哪个品牌的就可以买到同一个品牌的ipad和iphone
应用抽象工厂模式的设计
优点
缺点
深度思考
spring容器是最大的工厂
BeanFactory.getBean("xxx")
FileSystemXmlApplicationContext/ClassPathXmlApplicationContext
下面吐槽一下郭大神
考虑一下郭大神的家谱
...
郭大神的祖父
|
郭大神的父亲
|
郭大神
|
郭大神的儿子
...
郭大神的祖父创造了郭大神的父亲,郭大神的父新创造了郭大神,郭大神创造了郭大神的儿子
盘哥这边呢
...
盘哥的祖父
|
盘哥的父亲
|
盘哥
|
盘哥的儿子
...
用类来表示
如果我把郭明先生的祖父换成了姓郑(盘哥姓郑),则
当我换掉Grandfather时,奇迹出现了,整个家族的姓都变了。
从上面来看其实是工厂模式与工厂模式组合使用,经过组合后我们能写出具备极其扩展性的代码。
上面的原理是把工厂抽象成是一个产品(就是把工厂也当成是产品,那么生产这个产品的就是工厂的工厂。),于是就出现了"工厂的工厂的工厂"生产出"工厂的工厂","工厂的工厂"生产"工厂",最后工厂生成产品。这样就是级联使用工厂。
我们可以在任意一个环节替换实现,于是可以产生一个从大到小的扩展点。
考虑一下我们的建站平台框架的设计
站点有站点的接口, 同时还有站点资源接口(静态资源:js,css), 站点渲染接口, 站点数据接口。站点数据又可以分为站点数据读取接口, 和站点数据变更接口。
如果我设计下面这样的一个接口
经过上面这样设计之后, 如果我替换了SiteAPIFactory的实现, 我就可以操控整个站点的所有接口实现, 当我只替换SiteDataAPI时我能控制站点读取与写入数据的实现。也就是说从大到小的粒点扩展点我都支持了。做为平台的设计, 应用就可以根据需要自行替换实现。从而达到各种粒度的扩展。
很多模式都能组合起来使用,同时许多模式能与自身组合使用,像工厂,桥接等等
同时如果我写个SiteAPIUtil的获取SiteAPIFacotry,于是我就能提供所有接口了
再认真思考一下,你会发现SiteAPIUtil其实也是一个简单工厂,可以命名为SiteAPISimpleFactory
4.模板方法
考察一下郭大神与盘哥是如何上班的
不用模式的设计
不用模式有何问题?
他们两个上班过程基本上是一样的, 出现了重复的代码。
再考察一个人得同样要写很多重复的代码。
应用模式的设计
优点
没有重复的代码了,新增一个人时也同样减少一直重复的代码
如果在上班完加一个先吃个饭再回家,则只需要在抽象类里加上这行代码,无需改动所有Person
缺点
多出一个类,有时多出好几个方法
深度思考
模式方法模式其实就是一个抽象的过程,是最小抽象,位于抽象的最低层
与工厂方法的区别
总结:
简单工厂能把具体实现包装起来,让客户端真正达到面向接口编程
工厂方法可以在高层进行编码,让服务端的产品线真正达到面向接口编程
抽象工厂能聚合整个产品簇,让整个服务端的多个产品线真正达到面向接口编程
模板方法同样是在高层进行编码,也同样是面向接口编程。
但工厂方法及抽象工厂方法着重抽象的是产品,而模板方法着重抽象的是步骤。
而我们通常会两者一起结合起来使用。
思考上面那个模板模式,你会发现去上班和回到家代码很相似,
于是我们组合使用工厂模式又能去除重复代码。
在抽象类返回一个交通工具,上下班和回到家就可以在基类编程了。
代码如下:
这样,在AbstractPerson的子类只需要返回交通工具, 就可以少掉两个方法
1.简单工厂
郭大神和盘哥在说好想买ipad,用代码实现一下
不用模式的设计
public interface Product { String getDesc(); } public class IpadProduct implements Product { @Override public String getDesc() { return "Ipad2"; } } public class Client { public static void main(String[] args) { Product product = new IpadProduct(); System.out.println("郭大神说好想买" + product.getDesc() + ",但没钱!!!"); product = new IpadProduct(); System.out.println("盘哥说我好想买" + product.getDesc() + ",但没钱!!!"); } }
有何问题?
如果想买的iphone5时怎么办?
得找到所有new IpadProduct改成new IphoneProduct
而且改的是客户端的代码
应用模式的设计
public class IphoneProduct implements Product { @Override public String getDesc() { return "Iphone5"; } } public class SimpleFactory { public static Product getProdcut() { return new IpadProduct(); } } public class Client { public static void main(String[] args) { Product product = SimpleFactory.getProduct(); System.out.println("郭大神说好想买" + product.getDesc() + ",但没钱!!!"); product = SimpleFactory.getProduct(); System.out.println("盘哥说我好想买" + product.getDesc() + ",但没钱!!!"); } }
无模式遇到的问题如何解决?
只要在SimpleFactory.getProdcut()换成IphoneProdcut即可
优点
创建对象收拢,扩展性加强了。
扩展时不需要修改客户端代码。
对象创建与使用解耦
缺点
多出一个工厂类
2.工厂方法
应用工厂方法模式的设计
abstract public class Person { private String name; Person(String name){ this.name = name; } abstract Product getProduct(); public void say() { Product product = getProduct(); System.out.println(name + "说我好想买" + product.getDesc() + ",但没钱!!!"); } } public class GuoPerson extends Person { public GuoPerson(){ super("郭大神?); } @Override Product getProduct() { return new IpadProduct(); } } public class ShenPerson extends Person { public ShenPerson(){ super("盘哥"); } @Override Product getProduct() { return new IpadProduct(); } } public class ModeClient { public static void main(String[] args) { Person person = new GuoPerson(); person.say(); person = new ShenPerson(); person.say(); } }
优点
可以在不知道具体产品下实现编程
可以在不改变业务代码上很容易扩展出一个新的产品
缺点
多出几个具体工厂类
3.抽象工厂
考虑一下生产ipad和iphone的一个程序
工厂模式的设计有何问题?
public interface Ipad extends Product { } public class HongKongIpad implements Ipad { @Override public String getDesc() { return "香港版的Ipad"; } } public class USAIpad implements Ipad { @Override public String getDesc() { return "美国版的Iphone"; } } public interface Iphone extends Product { } public class HongKongIphone implements Iphone { @Override public String getDesc() { return "香港版的Iphone"; } } public class USAIphone implements Iphone { @Override public String getDesc() { return "美国版的Iphone"; } } public class SimpleFactory { public static Ipad createIpad(int type) { if (type == 1) { return new HongKongIpad(); } return new USAIpad(); } public static Iphone createIphone(int type) { if (type == 1) { return new HongKongIphone(); } return new USAIphone(); } } public class Client { public static void main(String[] args) { Ipad ipad = SimpleFactory.createIpad(1); Iphone iphone = SimpleFactory.createIphone(1); System.out.println("我采购的是:" + ipad.getDesc() + "和" + iphone.getDesc()); // ipad = SimpleFactory.createIpad(2); // iphone = SimpleFactory.createIphone(2); // System.out.println("我采购的是:" + ipad.getDesc() + "和" + iphone.getDesc()); } }
工厂模式的设计有何问题?
客户端想只买一家公司的产品,客户端需要了解每种类型是出自哪一家公司?
港版ipad与iphone是出自同一家公司,美版ipad与iphone也是出自同一样公司,对于采购时
它只要报一下要什么哪个品牌的就可以买到同一个品牌的ipad和iphone
应用抽象工厂模式的设计
public interface AppleFactory { Ipad createIpad(); Iphone createIphone(); } public class HongKongCompanyAppleFactory implements AppleFactory { @Override public Ipad createIpad() { return new HongKongIpad(); } @Override public Iphone createIphone() { return new HongKongIphone(); } } public class USACompanyAppleFactory implements AppleFactory { @Override public Ipad createIpad() { return new USAIpad(); } @Override public Iphone createIphone() { return new USAIphone(); } } public class ModeClient { public static void main(String[] args) { AppleFactory appleFactory = new HongKongCompanyAppleFactory(); Ipad ipad = appleFactory.createIpad(); Iphone iphone = appleFactory.createIphone(); System.out.println("我采购的是:" + ipad.getDesc() + "和" + iphone.getDesc()); // appleFactory = new USACompanyAppleFactory(); // ipad = appleFactory.createIpad(); // iphone = appleFactory.createIphone(); // System.out.println("我采购的是:" + ipad.getDesc() + "和" + iphone.getDesc()); } }
优点
缺点
深度思考
spring容器是最大的工厂
BeanFactory.getBean("xxx")
FileSystemXmlApplicationContext/ClassPathXmlApplicationContext
下面吐槽一下郭大神
考虑一下郭大神的家谱
...
郭大神的祖父
|
郭大神的父亲
|
郭大神
|
郭大神的儿子
...
郭大神的祖父创造了郭大神的父亲,郭大神的父新创造了郭大神,郭大神创造了郭大神的儿子
盘哥这边呢
...
盘哥的祖父
|
盘哥的父亲
|
盘哥
|
盘哥的儿子
...
用类来表示
interface Grandfather{ Father createFather(); } interface Father{ Self createSelf(); } interface Self { Son createSon(); }
如果我把郭明先生的祖父换成了姓郑(盘哥姓郑),则
当我换掉Grandfather时,奇迹出现了,整个家族的姓都变了。
从上面来看其实是工厂模式与工厂模式组合使用,经过组合后我们能写出具备极其扩展性的代码。
上面的原理是把工厂抽象成是一个产品(就是把工厂也当成是产品,那么生产这个产品的就是工厂的工厂。),于是就出现了"工厂的工厂的工厂"生产出"工厂的工厂","工厂的工厂"生产"工厂",最后工厂生成产品。这样就是级联使用工厂。
我们可以在任意一个环节替换实现,于是可以产生一个从大到小的扩展点。
考虑一下我们的建站平台框架的设计
站点有站点的接口, 同时还有站点资源接口(静态资源:js,css), 站点渲染接口, 站点数据接口。站点数据又可以分为站点数据读取接口, 和站点数据变更接口。
如果我设计下面这样的一个接口
interface SiteAPIFactory { getSiteAPI(); } interface SiteAPI{ getSiteResourceAPI(); getSiteDataAPI(); getRenderAPI(); } interface SiteDataAPI{ getSiteDataReadAPI(); getSiteDataDesignAPI(); } interface SiteDataReadAPI{ getSiteData(); } interface SiteDataDesignAPI{ updateSiteData(); deleteSiteData(); }
经过上面这样设计之后, 如果我替换了SiteAPIFactory的实现, 我就可以操控整个站点的所有接口实现, 当我只替换SiteDataAPI时我能控制站点读取与写入数据的实现。也就是说从大到小的粒点扩展点我都支持了。做为平台的设计, 应用就可以根据需要自行替换实现。从而达到各种粒度的扩展。
很多模式都能组合起来使用,同时许多模式能与自身组合使用,像工厂,桥接等等
同时如果我写个SiteAPIUtil的获取SiteAPIFacotry,于是我就能提供所有接口了
SiteAPIUtil{ SiteAPIFactory getSiteAPIFactory(){ DefaultSiteAPIFactory.instance }; SiteAPI getSiteAPI(){ getSiteAPIFactory().getSiteAPI(); }; SiteDataAPI getSiteDataAPI(){ getSiteAPI().getSiteDataAPI(); }; SiteDataDesignAPI getSiteDataDesignAPI(){ getSiteDataAPI().getSiteDesignAPI(); } ... }
再认真思考一下,你会发现SiteAPIUtil其实也是一个简单工厂,可以命名为SiteAPISimpleFactory
4.模板方法
考察一下郭大神与盘哥是如何上班的
不用模式的设计
public interface Person { String getName(); void summary(); } public class GuoPerson implements Person { @Override public void summary() { System.out.println(getName() + "起床"); System.out.println(getName() + "坐公交去上班"); System.out.println(getName() + "上班到9点时上了一次厕所"); System.out.println(getName() + "上班到10点时上了一次厕所"); System.out.println(getName() + "上班到11点时上了一次厕所"); System.out.println(getName() + "坐公交回到家"); System.out.println(getName() + "洗个澡睡觉了"); } @Override public String getName() { return "郭大神"; } } public class ShenPerson implements Person { @Override public void summary() { System.out.println(getName() + "起床"); System.out.println(getName() + "骑自行车去上班"); System.out.println(getName() + "上班到10点时上了一次厕所"); System.out.println(getName() + "骑自行车回到家"); System.out.println(getName() + "洗个澡睡觉了"); } @Override public String getName() { return "盘哥"; } } public class Client { public static void main(String[] args) { Person person = new GuoPerson(); person.summary(); person = new ShenPerson(); person.summary(); } }
不用模式有何问题?
他们两个上班过程基本上是一样的, 出现了重复的代码。
再考察一个人得同样要写很多重复的代码。
应用模式的设计
abstract public class AbstractPerson implements Person { public void summary() { System.out.println(getName() + "起床"); goToCompany(); work(); backToHome(); System.out.println(getName() + "洗个澡睡觉了"); } abstract public void goToCompany(); abstract public void work(); abstract public void backToHome(); } public class GuoPerson extends AbstractPerson { @Override public String getName() { return "郭大神"; } @Override public void goToCompany() { System.out.println(getName() + "坐公交去上班"); } @Override public void work() { System.out.println(getName() + "上班到9点时上了一次厕所"); System.out.println(getName() + "上班到10点时上了一次厕所"); System.out.println(getName() + "上班到11点时上了一次厕所"); } @Override public void backToHome() { System.out.println(getName() + "坐公交回到家"); } } public class ShenPerson extends AbstractPerson { @Override public String getName() { return "盘哥"; } @Override public void goToCompany() { System.out.println(getName() + "骑自行车去上班"); } @Override public void work() { System.out.println(getName() + "上班到10点时上了一次厕所"); } @Override public void backToHome() { System.out.println(getName() + "骑自行车回到家"); } } public class ModelClient { public static void main(String[] args) { Person person = new GuoPerson(); person.summary(); person = new ShenPerson(); person.summary(); } }
优点
没有重复的代码了,新增一个人时也同样减少一直重复的代码
如果在上班完加一个先吃个饭再回家,则只需要在抽象类里加上这行代码,无需改动所有Person
缺点
多出一个类,有时多出好几个方法
深度思考
模式方法模式其实就是一个抽象的过程,是最小抽象,位于抽象的最低层
与工厂方法的区别
总结:
简单工厂能把具体实现包装起来,让客户端真正达到面向接口编程
工厂方法可以在高层进行编码,让服务端的产品线真正达到面向接口编程
抽象工厂能聚合整个产品簇,让整个服务端的多个产品线真正达到面向接口编程
模板方法同样是在高层进行编码,也同样是面向接口编程。
但工厂方法及抽象工厂方法着重抽象的是产品,而模板方法着重抽象的是步骤。
而我们通常会两者一起结合起来使用。
思考上面那个模板模式,你会发现去上班和回到家代码很相似,
于是我们组合使用工厂模式又能去除重复代码。
在抽象类返回一个交通工具,上下班和回到家就可以在基类编程了。
代码如下:
public interface Vehicle { String by(); } public class Bus implements Vehicle { @Override public String by() { return "坐公交车"; } } public class Bike implements Vehicle { @Override public String by() { return "骑自行车"; } } abstract public class AbstractPerson implements Person { public void summary() { Vehicle vehicle = getVehicle(); System.out.println(getName() + "起床"); System.out.println(getName() + vehicle.by() + "去上班"); work(); System.out.println(getName() + vehicle.by() + "回到家"); System.out.println(getName() + "洗个澡睡觉了"); } abstract public Vehicle getVehicle(); abstract public void work(); } public class GuoPerson extends AbstractPerson { @Override public String getName() { return "郭大神"; } @Override public void work() { System.out.println(getName() + "上班到9点时上了一次厕所"); System.out.println(getName() + "上班到10点时上了一次厕所"); System.out.println(getName() + "上班到11点时上了一次厕所"); } @Override public Vehicle getVehicle() { return new Bus(); } } public class ShenPerson extends AbstractPerson { @Override public String getName() { return "盘哥"; } @Override public void work() { System.out.println(getName() + "上班到10点时上了一次厕所"); } @Override public Vehicle getVehicle() { return new Bike(); } }
这样,在AbstractPerson的子类只需要返回交通工具, 就可以少掉两个方法
- designmode.rar (10.5 KB)
- 下载次数: 2
相关推荐
2. **创建型模式**:包括单例模式、工厂模式(简单工厂、工厂方法、抽象工厂)、建造者模式、原型模式等,它们关注于如何创建对象,减少类之间的耦合。 3. **结构型模式**:如适配器模式、装饰器模式、代理模式、...
《设计模式解析》这一标题暗示了书籍将深度探讨各种设计模式,包括其原理、应用及背后的思维逻辑,帮助读者掌握并灵活运用这些模式来优化软件设计。 #### 描述解析:设计模式的入门与精通之路 描述中提到设计模式...
首先,我们来看三个主要的设计模式:抽象工厂、模板模式和装饰器模式。 **抽象工厂模式**(Abstract Factory Pattern)是一种创建型设计模式,它提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体...
深度学习使机器模仿视听和思考等人类的活动,解决了很多复杂的模式识别难题,使得人工智能相关技术取得了很大进步。 [1] 深度学习是一类模式分析方法的统称,就具体研究内容而言,主要涉及三类方法: [2] (1)基于...
《Java与模式 阎宏 摘录》是一本深度探讨Java编程语言与设计模式的书籍,由著名IT专家阎宏所著。这本书旨在帮助Java开发者深入理解面向对象设计原则,掌握并应用各种设计模式,提升软件开发的效率和质量。通过摘录,...
总的来说,《设计新思维:范型编程与设计模式之应用》是一本深度与广度兼备的C++技术指南,它不仅教导读者如何运用范型编程和设计模式,还启发了开发者对于软件设计的全新思考方式。通过阅读这本书,无论是初学者...
设计模式是解决特定软件设计问题的模板或框架,它提供了一种标准化的方法来处理常见的编程挑战。与面向对象设计相比,设计模式强调的是行为封装而非单纯的继承。这意味着设计模式关注于如何组织代码,使其具有更高的...
GoF)定义的23种经典设计模式,包括但不限于Strategy(策略)、Observer(观察者)、Decorator(装饰器)、Abstract Factory(抽象工厂)、Factory Method(工厂方法)、Singleton(单例)、Command(命令)、...
STEM教育的普及和深入发展为各国教育模式的创新提供了模板,这对于深度学习的教学创新具有重要的参考价值。 6. 实验重构与系统工程: 深度学习的实施被看作是一项系统工程。这要求教育者不仅仅将重点放在技术上,...
《C++沉思录》是一部深度剖析C++哲学与实践的著作,它引导读者思考如何编写优雅、高效的C++代码。书中涵盖了C++的关键特性,如面向对象编程、模板元编程、异常处理和STL(标准模板库)的使用。通过阅读此书,开发者...
5. **设计模式理解**:表明对Java设计模式的掌握程度,如单例模式和工厂模式,这反映了解决复杂问题的能力。 6. **项目经验**:列举实际项目经验,如本例中的网上购物系统。详细说明项目的技术栈、功能实现和自己的...
- **行为型模式**:包括策略模式、模板方法模式、观察者模式、迭代器模式、访问者模式、命令模式、备忘录模式、状态模式、解释器模式等。这些模式侧重于对象间的交互方式。 #### 五、结语 《Head First Design ...
6. **设计模式**:设计模式是解决软件设计中常见问题的经验总结,如工厂模式、单例模式、装饰器模式等,熟练运用设计模式能提升代码质量。 接下来,我们将逐一分析压缩包内的文件,它们代表了C++高级编程在不同领域...
《C++设计新思维》是一本深入探讨C++编程技巧和设计模式的书籍,它将泛型编程与设计模式的概念巧妙地结合在一起,为程序员提供了一种全新的思考方式。在C++的世界里,理解并掌握这些知识对于提升编程效率和写出高...
总的来说,文章揭示了当前软件技术专业校企合作模式的优点与不足,为深化产教融合提供了思考路径。未来,教育机构应持续探索与企业的紧密合作,既要满足行业需求,也要关注学生的个性化成长,以期在培养高素质技术...
作者提倡探讨和推广能引导这三个主体走向成功的"方法论和模式",方法论是系统性的思考工具,帮助解决根本问题,而模式则是可复用的解决方案模板,如设计模式、编程规范等。 解决软件危机的关键在于发展和应用能够...
75_适配器模式与模板方法模式在入站处理器中的应用 76_Netty项目开发过程中常见且重要事项分析 77_Java NIO Buffer总结回顾与难点拓展 78_Netty数据容器ByteBuf底层数据结构深度剖析 79_Netty的ByteBuf底层实现大...
Channel选择器工厂与轮询算法及注册底层实现 72_Netty线程模型深度解读与架构设计原则 73_Netty底层架构系统总结与应用实践 74_Netty对于异步读写操作的架构思想与观察者模式的重要应用 75_适配器模式与模板方法模式...
《Head_First_Design_Patterns》是一本专...总之,《Head_First_Design_Patterns》不仅是一本技术书籍,它还引导读者思考如何通过设计模式来优化软件架构,提高代码质量,是一本值得每个软件开发者深度阅读的经典之作。