博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式-工厂模式三部曲
阅读量:5915 次
发布时间:2019-06-19

本文共 7543 字,大约阅读时间需要 25 分钟。

设计模式-工厂模式三部曲(转)

转自:

 

工厂模式三部曲之一_简单工厂模式

转自:

 

      这段时间想要好好了解下工厂模式,从而在园中看了很多博友的关于工厂模式的博客, 受益匪浅......同时也感谢各位博友对知识的无私的分享....知识在于积累,但个人觉得积累知识的最好方式是当自己学懂了某个知识点之后,进行一番总结,将学到的东西再慢慢的推理一遍,再细细的消化一遍,进而转变为自己的东西.......

简单工厂模式

简单工厂模式又叫做静态工厂模式,顾名思义,它就是用来实例化目标类的静态类即客户端不需要负责“创建”对象的职责,只要通过这个静态类来创建出对应的类的实例返回给客户端,客户端只需要负责“消费”就可以了。。。

【解决问题】:如何去实例化一个合适的对象

【核心思想】:有一个专门的类类负责创建实例的过程 并返回给实例的对象 

【角      色】

工厂类角色:担任这个角色的简单工厂模式的核心,工厂类在客户端的直接调用下 创建产品对象并返回该对象。 

抽象产品角色:担任这个角色的类是工厂类所创建的对象的父类,或者他们有共同的接口。 

具体产品角色:工厂类所创建的任何对象都是这个角色的实例 

 

下面介绍一个例子来进行讲解

首先了解下现实场景:一个人总有很多件不同类型的衣服来适应不同的场合,怎么样用程序来实现呢??

对该场景进行分析:

工厂类:根据场合,获得相应衣服---
CreateCloth()方法
抽象产品:衣服具有一些共同的特征,或者定义公共方法或者属性,放在此类中----
-abstract:GetCloth()抽象方法
具体产品:衣服 继承与接口或者抽象 同时具有自身的特点

 

接下来贴上代码:

抽象产品类:定义了一个公共的方法GetCloth(),用来获取对应的衣服 

1  
//
抽象产品:获取衣服
2     
public 
abstract 
class Cloth
3     {
4        
public 
abstract 
void GetCloth();
5     }

 

具体产品类:定义了三种具体的产品:商务装、休闲装、运动装,都继承于抽象产品类,重写了抽象产品类中的抽象方法

 1    
//
具体产品1:商务装
 2     
class 商务装 : Cloth
 3     {
 4         
public 
override 
void GetCloth()
 5         {
 6             Console.WriteLine(
"
商务装......
");
 7         }
 8     }
 9 
10     
//
具体产品2:运动装
11     
class 运动装 : Cloth
12     {
13         
public 
override 
void GetCloth()
14         {
15             Console.WriteLine(
"
运动装.....
");
16         }
17     }
18 
19     
//
具体产品3:休闲装
20     
class 休闲装 : Cloth
21     {
22         
public 
override 
void GetCloth()
23         {
24             Console.WriteLine(
"
休闲装.......
");
25         }
26     }

 

 工厂类():根据客户端传入的参数来实例化对应类的对象 并返回该对象给客户端(这里的参数为服装类型拼音的小写首字母),定义了一个CreateCloth()方法----当然,这里的类型必须是已知的,也可以将类型放置于配置文件中来进行扩展,,便于类型的添加和修改........

 1      
//
工厂类:根据客户端条件 创建并返回对象
 2     
public 
class ClothFactory
 3     { 
 4         
 5        
public 
static Cloth CreateCloth(
string clothtype)
 6        {
 7            Cloth cloth = 
null;
 8             
switch(clothtype)
 9             {
10                 
case 
"
sw
":
11                     cloth = 
new 商务装();
12                     
break;
13                 
case 
"
yd
":
14                     cloth = 
new 运动装();
15                     
break;
16                 
case 
"
xx
":
17                     cloth = 
new 休闲装();
18                     
break;
19                 
default:
20                     cloth = 
null;
21                     
break;
22             }
23             
return cloth;
24        }

 

客户端:调用工厂类的静态方法,传入合适的参数获取对应对象

 1         
//
客户端
 2         
static 
void Main(
string[] args)
 3         {
 4             
//
要求商务装
 5             Cloth cloth = ClothFactory.CreateCloth(
"
sw
");
 6             cloth.GetCloth();
 7 
 8             
//
要求运动装
 9             Cloth clothsport = ClothFactory.CreateCloth(
"
yd
");
10             clothsport.GetCloth();
11 
12             Console.ReadKey();
13         }

 

 

总结优缺点:

优点:用户在使用时是根据工厂类去创建所需的对象实例,而无需了解是如何创建和组织这种细节问题,有利于软件体系结构的优化

缺点:1.创建和不同实例对象的操作都在一个类中完成,即不符合单一职责的原则

        2.当需要添加或者删除某个功能是会比较麻烦,需要修改工厂类,违背了开放-封闭的原则(对修改封闭,对扩展开放)

        3.工厂类中的方法为static静态方法(静态工厂方法),不能通过继承来改变创建行为

 

        嘿嘿,既然是工厂模式三部曲...当然还有后续的工厂模式和抽象工厂模式了..........敬请关注............. 

 

 

工厂模式三部曲之二_工厂模式

转自:

 

      自之后,貌似已经很久没有继续这个三部曲了,所以抽点时间把后两篇给补上吧。首先回顾下简单工厂模式的主要内容:简单工厂模式就是实质就是专门定义了一个工厂类,利用工厂类的静态方法来根据用户需求创建对象,优点是客户端的压力较小,客户端不需要做创建实例的操作,只需要调用工厂类中的方法就可以获得对应实例,而其缺点也非常明显,其所有创建工作都在一个工厂类完成,耦合性较高,而且当系统需要增加或者修改产品时需要改动工厂类,既不符合单一职责的原则也不符合开放-关闭原则,所以就出现了工厂模式。

 

工厂模式 

工厂模式是对简单工厂模式的进一步抽象化,是简答工厂模式的衍生,根据设计模式的基本原则也是设计模式的精髓“封装变化点”,即哪里发生改变就把哪里封装起来,所以工厂模式对简单工厂中的工厂类做了一个封装,使其满足单一职责和开放-关闭原则。

【解决问题】:简单工厂模式中违背了单一职责和开放-关闭原则。

【核心思想】:建立一个抽象工厂的基类,给每个产品建立一个工厂,该工厂继承之抽象工厂,规定每个产品都有特定的工厂来创建。

【角色】

抽象工厂角色:这是工厂模式的核心,它与应用程序无关,是具体工厂必须继承的父类或者必须实现的接口

具体工厂角色:包含逻辑业务的代码,由应用程序调用以创建对应的具体产品对象

抽象产品角色:具体产品必须继承的父类或者必须实现的接口

具体产品角色:所创建的对象就是此角色的实例 

 

下面仍旧以简单工厂中的实例来讲解,对其进行改造

【角色分析】

抽象工厂:衣服制造厂 包含衣服的一些公共特性
具体工厂:**类型衣服制造厂 每个衣服制造厂只负责一件衣服(高内聚) ,当然也就是说当没有客户需要的衣服的时候需要创建一个对应的工厂及一件衣服 由该工厂负责提供这件衣服 但是对于以前的工厂和衣服都没有影响(这是设计模式所期望的--单一职责原则)
抽象产品:衣服 包含衣服的一些公共特性
具体产品:**类型衣服 继承抽象产品,当然可扩展自身特性

角色分析好了,就可以进行改造了,贴上改造完毕的各个部分代码: 

抽象工厂类:

1     
//
抽象工厂:声明工厂方法 返回一个产品
2     
public 
abstract 
class ClothFactory
3     {
4        
public 
abstract Cloth CreateCloth();
5     }

该类中定义了一个抽象的CreateCloth()方法,用于创建衣服实例。

 

具体工厂类:

 1     
//
具体工厂1:商务装工厂 只负责生产商务装
 2     
public 
class BusinessFactory : ClothFactory
 3     {
 4         
public 
override Cloth CreateCloth()
 5         {
 6             
return 
new BusinessCloth();
 7         }
 8     }
 9 
10     
//
具体工厂2:运动装工厂 只负责生产运动装
11     
public 
class SportFactory : ClothFactory
12     {
13         
public 
override Cloth CreateCloth()
14         {
15             
return 
new SportCloth();
16         }
17     }
18 
19     
//
具体工厂3:校服工厂 只负责生产校服
20     
public 
class LifeFactory : ClothFactory
21     {
22         
public 
override Cloth CreateCloth()
23         {
24             
return 
new LifeCloth();
25         }
26     }

该类为核心,类中定义了BusinessFactorySportFactory,LifeFactory三个工厂分别来创建商务装运动装校服,三个工厂都继承之抽象工厂ClothFactory,并都重写了抽象工厂中的CreateCloth()方法,分别用来创建该工厂生产的衣服,利用里氏替换原则(子类代替父类)来实现,这是产品需要改变(添加,修改,删除)时,如添加,只需要添加一个专门生产该产品的工厂和该产品就可以了,添加操作对之前所有的工厂和产品没有直接的影响。修改同理,只需要修改创建该产品的工厂类就可以了,很好的遵循了开放-关闭原则,同时一个工厂类创建一个产品,遵循了单一职责的原则。

 

抽象产品类:

1    
//
定义抽象产品:衣服
2     
public 
abstract 
class Cloth
3     {
4        
public 
abstract 
void GetCloth();
5     }

该方法不需要作改变,仍旧定义了一个GetCloth()方法,模拟使用产品。

 

具体产品类:

 1     
//
定义具体产:1:商务装
 2     
class BusinessCloth : Cloth
 3     {
 4         
public 
override 
void GetCloth()
 5         {
 6             Console.WriteLine(
"
商务装......
");
 7         }
 8     }
 9 
10     
//
定义具体产品2:运动装
11     
class SportCloth : Cloth
12     {
13         
public 
override 
void GetCloth()
14         {
15             Console.WriteLine(
"
运动装.......
");
16         }
17     }
18 
19     
//
定义具体产品3:休闲服
20     
class LifeCloth : Cloth
21     {
22         
public 
override 
void GetCloth()
23         {
24             Console.WriteLine(
"
休闲服........
");
25         }
26     }

该类也不需要作任何改变,根据哪里封装改变哪里,工厂类的封装和产品没有直接的影响,仍旧定义了三种类型的衣服,并重写抽象产品中的抽象方法,因为每种产品都有自身特性,有自身独特的功能。

 

客户端: 

 1     
//
客户端
 2     
class Program
 3     {
 4         
static 
void Main(
string[] args)
 5         {
 6             
//
要求商务装
 7             Cloth c = 
new BusinessFactory().CreateCloth();
 8             c.GetCloth();
 9 
10             
//
要求运动装
11             Cloth c2 = 
new SportFactory().CreateCloth();
12             c2.GetCloth();
13 
14             Console.ReadKey();
15         }
16     }

 

运行效果: 

 

 

优缺点总结:

优点:解决了简单工厂中违背单一职责和开放-关闭原则问题,同时增加了程序的可扩展性,屏蔽了产品类。

缺点:1.逻辑判断放在了客户端进行

        2.每添加一个产品都需要为它专门添加一个工厂用来生产,繁杂

        3.每个工厂都只能生产一种产品,品种单一。 

 

 

工厂模式三部曲之三_抽象工厂模式(附三部曲源码)

转自:

 

      抽象工厂模式是对工厂模式的进一步抽象,是工厂模式中最为抽象和最具一般性的一种形态,提供了创建一系列相关或者相互依赖对象的接口,而无需指定他们的类型。

如果你对工厂模式还有些迷惑的,可以回顾下工厂模式的内容:。

 

下面直接引用园中某位博友运用的实例进行讲解:

生活场景:某家具厂为学校生产课桌和座椅,开始只生产木质的课桌和座椅,后来经学校要求,又开始为学校生产铁质的课桌和座椅。
设计目标:实现针对多种成套产品的生产,每套产品有多种不同等级结构的物品组成。
【分析】
抽象产品:虚拟课桌 虚拟椅子
具体产品:木课桌 铁课桌;木椅子 铁椅子
抽象工厂:要生产产品的基类:抽象产品
具体工厂:木工厂=》木桌子,木椅子   铁工厂=》铁桌子,铁椅子

 

角色分析好了就直接进入代码部分:

抽象工厂类:

1     
//
抽象工厂:生产课桌 生产椅子
2     
public 
abstract 
class Factory
3     {
4         
public 
abstract Desk CreateDesk();
5         
public 
abstract Chair CreateChair();     
6     }

该类中定义了两个抽象方法,一个用来生产桌子,一个用来成产椅子 

具体工厂类

 1     
//
具体工厂(木质产品工厂)
 2     
public 
class WoodFactory : Factory
 3     {
 4         
//
木桌子
 5         
public 
override Desk CreateDesk()
 6         {
 7             
return 
new WoodDesk();
 8         }
 9 
10         
//
木椅子
11         
public 
override Chair CreateChair()
12         {
13             
return 
new WoodChair();
14         }
15     }
16 
17     
//
具体工厂(铁质产品工厂)
18     
public 
class IronFactory : Factory
19     {
20         
//
铁桌子
21         
public 
override Desk CreateDesk()
22         {
23             
return 
new IronDesk();
24         }
25 
26         
//
铁椅子
27         
public 
override Chair CreateChair()
28         {
29             
return 
new IronChair();
30         }
31     }

抽象工厂是用来生产一系列相关产品,这里的桌子分木桌子和铁桌子,这两种桌子就是相关产品,同理,木椅子和铁椅子也是相关产品,所以具体工厂分为了木制工厂和铁制工厂,分别用来生产木质产品和铁质产品,所以这里工厂重写了抽象工厂中的抽象方法,分别创建了某种材质的实例。

抽象产品类:

 1     
//
抽象产品A:课桌
 2     
public 
abstract 
class Desk
 3     {
 4         
public 
abstract 
void ProductDesk(); 
 5     }
 6     
//
抽象产品B:椅子
 7     
public 
abstract 
class Chair
 8     {
 9        
public 
abstract 
void ProductChair();
10     }

工厂模式是一个抽象工厂一个抽象产品,抽象工厂模式是多个抽象工厂多个抽象产品。 

具体产品类:

 1     
//
具体产品A_1:木课桌
 2     
public 
class WoodDesk : Desk
 3     {
 4         
public 
override 
void ProductDesk()
 5         {
 6             Console.WriteLine(
"
Wood Desk.......
");
 7         }
 8     }
 9 
10     
//
具体产品A_2:铁课桌
11     
public 
class IronDesk : Desk
12     {
13         
public 
override 
void ProductDesk()
14         {
15             Console.WriteLine(
"
Iron Desk.......
");
16         }
17     }
18 
19     
//
具体产品B_1:木椅子
20     
public 
class WoodChair : Chair
21     {
22         
public 
override 
void ProductChair()
23         {
24             Console.WriteLine(
"
Wood Chair......
");
25         }
26     }
27 
28     
//
具体产品B_2:铁椅子
29     
public 
class IronChair : Chair
30     {
31         
public 
override 
void ProductChair()
32         {
33             Console.WriteLine(
"
Iron Chair.......
");
34         }
35     }

具体产品分系列,有铁质系列和木质系列两种,产品分别是桌子椅子。

客户端:

 1     
//
客户端
 2     
class Program
 3     {
 4         
static 
void Main(
string[] args)
 5         {
 6             
//
要求木桌子
 7             Desk desk = 
new WoodFactory().CreateDesk();
 8             desk.ProductDesk();
 9 
10             
//
要求铁椅子
11             Chair chair = 
new IronFactory().CreateChair();
12             chair.ProductChair();
13 
14             Console.ReadKey();
15 
16         }
17     }

 

运行效果: 

 

 

附上三部曲的所有源码: 

转载于:https://www.cnblogs.com/flylong0204/p/3392743.html

你可能感兴趣的文章
2018 German Collegiate Programming Contest (GCPC 18)
查看>>
前端之jquery
查看>>
静态类和非静态类
查看>>
关于日志表的自动创建及分表储存
查看>>
topcoder srm 315 div1
查看>>
【super vlan的配置】
查看>>
洛谷P1443 马的遍历
查看>>
日期字符串格式化
查看>>
ps基本操作
查看>>
JS-OO-数据属性,访问器属性
查看>>
unity3d 各键值对应代码
查看>>
10年程序员的一些人生感悟
查看>>
《统一沟通-微软-实战》-6-部署-7-部署移动功能-1
查看>>
ZEROCONF是什么
查看>>
【随便扯扯】Standby到底翻译成备用还是待机?
查看>>
信息系统项目管理师软考辅导——3年真题透解与全真模拟
查看>>
一个引号导致1个小时网站打不开
查看>>
从无到有,WebService Apache Axis2初步实践
查看>>
SQL Server 2012笔记分享-58:数据库文件管理2
查看>>
将字符串"123456"转换成"1,2,3,4,5,6"
查看>>