抽象工厂-模式设计
简说设计模式——抽象工厂模式
![简说设计模式——抽象工厂模式](https://img.taocdn.com/s3/m/7f2d5014640e52ea551810a6f524ccbff121ca29.png)
简说设计模式——抽象⼯⼚模式⼀、什么是抽象⼯⼚模式抽象⼯⼚模式其实就是多个,⽐如前⾯⼯⼚⽅法模式中,我们创建多个不同类型的数据库,有MySQL、SQLServer等等,就是⽤⼯⼚⽅法模式来实现的,但此时我们只能实现⼀个表(具体内容见下⽅⼯⼚模式的实现),我们数据库中当然不可能只有⼀个表呀,所以抽象⼯⼚模式就来了。
抽象⼯⼚模式(Abstract Factory),提供⼀个创建⼀系列相关或相互依赖对象的接⼝,⽽⽆需指定它们具体的类。
UML结构图如下:其中,AbstractFactory是抽象⼯⼚接⼝,⾥⾯包含所有的产品创建的抽象⽅法;ConcreteFactory则是具体的⼯⼚,创建具有特定实现的产品对象;AbstractProduct是抽象产品,有可能由两种不同的实现;ConcreteProduct则是对于抽象产品的具体分类的实现。
抽象⼯⼚模式是⼯⼚⽅法模式的升级版本,在有多个业务品种、业务分类时,通过抽象⼯⼚模式产⽣需要的对象是⼀种⾮常好的解决⽅式。
下⾯是抽象⼯⼚模式的通⽤源代码类图:1. AbstractFactory类下述代码是⼀个抽象⼯⼚类,它的职责是定义每个⼯⼚要实现的功能,有n个产品族,在抽象⼯⼚类中就应该有n个创建⽅法。
这⾥按上述类图,给出A、B两个产品族,即构造两个⽅法。
1public abstract class AbstractFactory {23//创建A产品家族4public abstract AbstractProductA createProductA();5//创建B产品家族6public abstract AbstractProductB createProductB();78 }2. AbstractProduct类抽象产品类,两个抽象产品类可以有关系,例如共同继承或实现⼀个抽象类或接⼝。
这⾥给出A产品的抽象类,产品类B类似,不再赘述。
1public abstract class AbstractProductA {23//每个产品共有的⽅法4public void shareMethod() {}5//每个产品相同⽅法,不同实现6public abstract void doSomething();78 }3. ConcreteFactory类具体⼯⼚实现类,如何创建⼀个产品是由具体的实现类来完成的。
抽象工厂模式(一)
![抽象工厂模式(一)](https://img.taocdn.com/s3/m/dadbbeca05a1b0717fd5360cba1aa81144318f3d.png)
抽象工厂模式(一)抽象工厂模式(Abstract Factory Pattern)是一种对象创建型设计模式,属于工厂模式的扩展版。
它通过定义一个抽象工厂来统一创建一系列相关或相互依赖的对象,而这些对象之间具有一定的约束关系,即它们属于同一个产品族。
抽象工厂模式的实现过程中,需要定义抽象工厂类和具体工厂类以及抽象产品类和具体产品类。
具体工厂类实现抽象工厂类的所有抽象方法,用于创建同一产品族的不同具体产品,同时具体产品类继承自抽象产品类,用于定义一类产品的共性和差异性。
抽象工厂模式的实现具有以下几个优点:1. 隐藏对象创建过程:抽象工厂模式可以将对象的创建过程隐藏起来,并且只需要使用工厂类即可创建所有相互依赖的对象,因此可以降低系统中对象的耦合度。
2. 提供一个封装的工厂接口:抽象工厂模式提供一个工厂接口用于创建产品族,客户端通过使用这个接口来创建需要的产品,而无需关心产品的具体实现。
3. 简化了使用者的代码:抽象工厂模式可以将对象的创建和使用分离开来,避免了一系列的对象创建和初始化的问题,并且能够简化使用者的代码。
4. 具有良好的扩展性:由于抽象工厂模式通过抽象接口提供统一的工厂方法,因此可以方便地增加新的产品族和产品等扩展功能。
5. 符合开闭原则:抽象工厂模式对扩展开放,对修改封闭,因此它符合开闭原则的要求。
在使用抽象工厂模式时,有一些需要注意的地方:1. 需要考虑产品族的扩展问题:抽象工厂模式一般用于创建一系列相关的产品,如果需要增加新的产品族,需要修改抽象工厂接口和所有的实现类,因此需要考虑到产品族扩展的问题。
2. 可能会增加系统的复杂度:使用抽象工厂模式可能会增加代码的复杂度,因为需要创建一系列的抽象类和实现类,但这也是保证抽象工厂模式功能强大的原因。
3. 需要考虑产品等级的问题:抽象工厂模式适用于创建一系列相关或相互依赖的对象,如果要创建多个产品等级结构的对象,可能需要使用其他的设计模式。
简单工厂模式、工厂模式和抽象工厂模式区别及优缺点
![简单工厂模式、工厂模式和抽象工厂模式区别及优缺点](https://img.taocdn.com/s3/m/769074db29ea81c758f5f61fb7360b4c2e3f2a72.png)
简单⼯⼚模式、⼯⼚模式和抽象⼯⼚模式区别及优缺点各位⼩伙伴好,今天给⼤家主要介绍⼀下简单⼯⼚模式、⼯⼚模式和抽象⼯⼚模式的区别及各⾃的优缺点。
(本⽂实现语⾔为Python3)【前⾔】众所周知今天所讲的内容是设计模式的⼀类;对于设计模式这个概念,我想⾸先请⼤家问问⾃⼰:1、什么是设计模式 2、我们为什么要了解并学习设计模式?从我上学的时候我相信⼤家跟我⼀样也接触过设计模式的课程,当时可能懵懵懂懂只是知其然,当时还会想明明可以直接写出来为什么要搞成这样的形式,我就算学会了它到底什么时候能⽤呢?⼀系列的问题...Emm算了到时候再想想(lazy)。
随着实践的不断增多,现在我想可以对这些问题有个初步的回答了: 1、在我看来,设计模式外在看是经过前⼈不断实践总结出的针对某些指定场景极其好⽤的⼀种代码结构设计模板;内在看其实是⼀种设计思想(即为什么他们会这么想,这样想较之其他⽅法有什么好处)。
当我们真正的理解设计思想的时候,就可能会在⾯对问题和场景时⾃然⽽然的灵活运⽤到多种设计模式,⽽不是单⼀的刻板结构。
2、在⼯程化的开发中,需求往往是会不断变化的,这也是让很多开发⼈员及其烦躁的地⽅,所以才会有开发与产品的亲密关系。
设计模式就是为了抵御外部需求变化产⽣的。
设计模式应符合开闭原则(类、模块和函数等应该对扩展开放,对修改关闭。
)⼀个好的设计在之后的开发中,包括发⽣重⼤需求变化的时候,往往代码只需要进⾏简单重构去进⾏适配,⽽不是通过打补丁的⽅式去堆砌,也很容易避免破窗效应,充分的发挥了灵活的扩展和适配,⼤⼤增强了维护性。
综上所述,我们了解并学习设计模式,可以使我们的代码变得更加健壮、结构清晰,可以从容、灵活的适配需求变更(可复⽤、可扩展、可维护、够灵活)【正⽂】⾸先,这三种模式解决的问题是实例化对象的问题;那么为什么不直接实例化⽽⽤这样的⼯⼚形式去实例化对象呢?因为【待实例化对象太多(⼦类多且变动、调⽤频繁)或者实例化对象的过程、准备⽐较复杂】,直接实例化意味着每次都⽤重复的去执⾏实例化这个操作,如果有很多待实例化的操作,那么就要重复执⾏很多次,更不要说万⼀在实例化之前还要执⾏⼀堆配置项的初始化。
工厂模式之抽象工厂
![工厂模式之抽象工厂](https://img.taocdn.com/s3/m/72b7f2fa162ded630b1c59eef8c75fbfc77d94d3.png)
⼯⼚模式之抽象⼯⼚主要参考《⼤话设计模式》1. 引⼊ 前⾯介绍的⼯⼚⽅法模式中考虑的是⼀类产品的⽣产,如畜牧场养动物、电视机⼚⽣产电视等,然⽽,现实⽣活中,许多⼯⼚是综合型⼯⼚,能够⽣产各类产品,如⼤学包括各个系。
2. 定义 抽象⼯⼚模式,为创建⼀组相关或相互依赖的对象提供⼀个接⼝,且⽆需指定它们的具体类。
是所有形态的⼯⼚模式中最为抽象和最具⼀般性的⼀种形态。
3. 场景实现3.1 场景描述 在框架开发中,对于同⼀个ORM,假如刚开始开发时使⽤SQL Server数据库,但是也希望能够连接Access数据库,或其他的数据库(如MySql、Oracle等)。
SQL Server在.net中使⽤的System.Data.SqlClient命名空间下的SqlConnection、SqlCommand、SqlParameter、SqlDataReader、SqlDataAdapter,⽽Access要⽤System.Data.Olede命名空间下的相应对象,我们不可能修改命名空间,或者重新写相同的业务代码只是修改与数据库相关的代码,这就是两倍的⼯作量。
因⽽,针对类似问题,可以采⽤抽象⼯⼚模式解决。
⽐如,现在要在业务逻辑代码相似的情况下,将SqlServer数据库改为使⽤Access数据库。
以“新增⽤户”和“获取⽤户”为例给出最基本的数据库访问程序。
3.2 最基本的数据访问程序 class User{private int _id;public int ID{get { return _id;}set { _id = value; }}private string _name;public string Name{get { return _name; }set { _name = value; }}} class SqlServer{public void insert(User user){Console.WriteLine("在sqlserver中为User表添加⼀条记录");}public void select(int id){Console.WriteLine("在sqlserver中根据⽤户id查找⽤户");}} static void Main(string[] args){User user = new User();SqlServer sql = new SqlServer();sql.insert(user);sql.select(1);Console.Read();}运⾏结果如下: 上述实现中,⽆法灵活的把sqlserver数据库替换成其他数据库,原因就是SqlServer sql = new SqlServer()使得sql对象被框死在Sqlserver上,如果此处是灵活的(多态的)应⽤,在执⾏sql.insert(user)时,不需要关注数据库到底是sqlserver还是access,因此,我们可以采⽤⼯⼚⽅法模式进⾏封装。
抽象工厂设计模式
![抽象工厂设计模式](https://img.taocdn.com/s3/m/05583fd749649b6648d747e0.png)
抽象工厂(Abstract Factory)设计模式目的:提供一个创建一系列相关或相互依赖对象的接口,无需指定它们具体的类。
别名:Kit“抽象”来自“抽象产品角色”,而“抽象工厂”就是“抽象产品角色的工厂”。
在简单工厂中,我们的工厂类一次只可以处理一类产品。
那么如果我们想处理多类产品,简单工厂是满足不了的,必须要用抽象工厂设计模式。
抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。
抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。
抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定具体产品类型的情况下,创建多个产品族中的对象。
当每个抽象产品都有多于一个的具体子类的时候,工厂角色怎么知道实例化哪一个子类呢?比如每个抽象产品角色都有两个具体产品。
抽象工厂模式提供两个具体工厂角色,分别对应于这两个具体产品角色,每一个具体工厂角色只负责某一个产品角色的实例化。
每一个具体工厂类只负责创建抽象产品的某一个具体子类的实例。
每一个模式都是针对一定问题的解决方案,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式针对的是多个产品等级结构。
成分:从上图可以看出,抽象工厂模式涉及到以下几类角色:1. 抽象工厂(AbstractFactory)角色:声明一个创建抽象产品对象的操作接口。
担任这个角色的是工厂方法模式的核心,它是与应用系统的商业逻辑无关的。
通常使用Java 接口或者抽象Java 类实现,而所有的具体工厂类必须实现这个Java 接口或继承这个抽象Java 类。
2. 实体工厂类(Conrete Factory)角色:这个角色直接在客户端的调用下实现创建具体产品对象的操作。
这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。
通常使用具体Java 类实现这个角色。
3. 抽象产品(Abstract Product)角色:为一类产品对象声明一个接口。
担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。
抽象工厂模式介绍
![抽象工厂模式介绍](https://img.taocdn.com/s3/m/d35cf6560a4e767f5acfa1c7aa00b52acfc79c03.png)
抽象工厂模式介绍抽象工厂模式是一种软件设计模式,它提供了一种创建一系列相互关联或依赖的对象的方法,而无需指定具体实现类。
该模式的核心思想是将对象的创建和使用分离,从而在系统设计中提供更高的灵活性和可扩展性。
抽象工厂模式基于工厂方法模式,它将工厂抽象化,允许客户端使用抽象工厂来创建一系列相关或依赖的对象,而不必关心具体的实现类。
通过使用抽象工厂模式,我们可以使系统更易于扩展和修改,满足不同的需求和变化。
抽象工厂模式的结构包括抽象工厂、具体工厂、抽象产品和具体产品。
抽象工厂定义了创建一系列相关或依赖对象的方法,具体工厂实现了这些方法。
抽象产品定义了一系列相关产品的接口,具体产品实现了这些接口。
通过抽象工厂和具体产品的组合,我们可以创建一系列具有关联性的对象。
抽象工厂模式的使用可以带来多种好处。
首先,它可以提供系统的灵活性。
由于抽象工厂将对象的创建和使用分离,我们可以很容易地替换具体的工厂实现,从而满足不同的需求和变化。
其次,它可以提供系统的可扩展性。
通过增加新的具体工厂和产品实现,我们可以方便地扩展系统的功能。
再次,它可以提供系统的可维护性。
由于抽象工厂模式将创建对象的代码集中于一个工厂类中,我们可以更容易地维护和修改代码。
最后,它可以提供系统的解耦性。
客户端只需要与抽象工厂和抽象产品进行交互,不需要了解具体产品的实现细节,从而降低了系统的耦合度。
抽象工厂模式的应用场景较为广泛。
一种常见的应用场景是在需要创建一系列相互依赖的对象的时候。
比如,在一个图形界面应用程序中,需要创建一系列按钮和文本框,它们都依赖于同一个主题。
通过使用抽象工厂模式,我们可以创建具有相同主题的按钮和文本框,保持它们的外观风格一致。
另一个应用场景是在需要创建一系列相关产品族的时候。
比如,在一个汽车制造系统中,需要生产不同品牌和型号的汽车,每个品牌和型号都由相应的零部件组成。
通过使用抽象工厂模式,我们可以为每个品牌和型号创建对应的汽车工厂和零部件工厂,从而保证汽车的组装作业能够顺利进行。
【设计模式-工厂模式】男男女女的抽象工厂模式
![【设计模式-工厂模式】男男女女的抽象工厂模式](https://img.taocdn.com/s3/m/016e97e47d1cfad6195f312b3169a4517723e5c9.png)
【设计模式-⼯⼚模式】男男⼥⼥的抽象⼯⼚模式背景虽然⼥娲已经成功将⼈类创造出来了,可是都是没有性别的,那么后续该如何繁衍呢。
为此,除了增加⼈种外,我们还需要增加所有⼈类都有的⼀个属性:性别。
由此:⼈种和性别相互组合⽣成6中不同的⼈类男⿊⼈、⼥⿊⼈、男⽩⼈、⼥⽩⼈、男黄⼈、⼥黄⼈原来的⼀个⼋卦炉也需要进⾏修改,变为专门⽣产男性的"男⼋卦炉" 和专门⽣产⼥性的 “⼥⼋卦炉”类图可以看到我们在原有的⼏个⼈种上,⼜重新继承并实现了两个类,分别⽤于表⽰不同⼈种的男⼥特别说明的是HumanFactory接⼝,在这个接⼝中定义了三个⽅法,分别⽤于⽣产不同的肤⾊的⼈种,也就是我们将肤⾊作为Y轴,性别作为X轴,通过X坐标和Y坐标唯⼀确定⼀个⽣产出来的对象。
代码⼈种接⼝public interface Human {//每个⼈种的⽪肤都是不同的颜⾊public void getColor();//每个⼈类都会发声public void talk();public void getSex();}⼈种接⼝即抽象产品,该产品的共同属性定义:肤⾊和语⾔,⽽性别则是不同产品下更深层的细分实现⼈种接⼝的黄种⼈public abstract class AbstractYellowHuman implements Human{@Overridepublic void getColor() {System.out.println("黄种⼈");}@Overridepublic void talk() {System.out.println("国语");}}继承了该接⼝的抽象黄种⼈类,每个抽象类都会实现产品的公共细节,⽽每个抽象类的都会有两个实现类,分别实现各⾃的不同的细节:性别黄种⼈⼥性public class YellowWoman extends AbstractYellowHuman{@Overridepublic void getSex() {System.out.println("YellowWoman");}}⼋卦炉/*** 产品类* 有N个产品组,在抽象⼯⼚类中就应该有N个创建⽅法;* 每个产品有M个产品扩展维度就应该有M个产品实现⼯⼚类,* 在每个实现⼯⼚中,实现不同的产品族的⽣产任务.* @author LiPeng01* @since 2020/8/8 7:31 下午*/public interface HumanFactory {public Human doYellowHuman();public Human doWhiteHuman();public Human doBlackHuman();}在接⼝中我们可以看到 抽象的⼯⼚是可以⽣产出不同肤⾊的⼈种的。
第6章抽象工厂模式
![第6章抽象工厂模式](https://img.taocdn.com/s3/m/091b646159fb770bf78a6529647d27284b7337ca.png)
第6章抽象工厂模式抽象工厂模式是一种创建型设计模式,旨在提供一个创建一系列相关或相互依赖对象的接口,而无需指定具体的类。
通过使用抽象工厂模式,可以使客户端与具体实例的创建分离,降低了客户端与具体实例之间的耦合度。
本文将详细介绍抽象工厂模式的定义、结构、应用场景以及优缺点。
一、定义抽象工厂模式,也称为Kit模式,是一种对象创建型模式。
它提供一个接口,用于创建一系列具有共同接口的相关或相互依赖的对象,而无需指定其具体实现类。
二、结构抽象工厂模式包含以下几个角色:1. 抽象工厂(Abstract Factory):定义了创建产品对象的接口,它包含了一组创建产品的方法。
2. 具体工厂(Concrete Factory):实现了抽象工厂中的方法,完成具体产品的创建。
3. 抽象产品(Abstract Product):定义了产品的接口,是具体产品类的父类。
4. 具体产品(Concrete Product):实现了抽象产品接口的具体产品类。
三、应用场景抽象工厂模式通常在以下几种情况下使用:1.系统需要一系列相关或相互依赖的对象,并且不希望客户端与具体实例之间有耦合。
2.客户端不应知道所使用的具体工厂和具体产品类的名称。
3.系统需要提供一种产品的多种实现,用户可以选择使用哪个实现。
四、优缺点抽象工厂模式具有以下优点:1.将具体产品的创建与使用解耦,客户端只需要知道使用抽象工厂即可。
2.通过切换具体工厂,可以改变系统的配置,实现不同产品簇的切换。
3.新增具体工厂和具体产品类只需实现对应的接口,符合开闭原则。
抽象工厂模式的缺点是:1.当产品簇需要新增产品时,需要修改所有的具体工厂类,不符合开闭原则。
2.当具体产品较多时,会导致具体工厂类的数量增加,难以管理。
五、代码示例我们以汽车和轮胎为例,介绍抽象工厂模式的代码实现。
首先,定义抽象工厂和抽象产品的接口:```java//抽象工厂public interface AbstractFactoryCar createCar(;Tire createTire(;//抽象产品public interface Carvoid drive(;//抽象产品public interface Tirevoid rotate(;```然后,实现具体工厂和具体产品的类:```java//具体工厂public class DomesticFactory implements AbstractFactory public Car createCareturn new DomesticCar(;}public Tire createTirreturn new DomesticTire(;}//具体工厂public class ForeignFactory implements AbstractFactory public Car createCareturn new ForeignCar(;}public Tire createTirreturn new ForeignTire(;}//具体产品public class DomesticCar implements Carpublic void drivSystem.out.println("国产汽车开始启动");}//具体产品public class ForeignCar implements Carpublic void drivSystem.out.println("进口汽车开始启动");}//具体产品public class DomesticTire implements Tire public void rotatSystem.out.println("国产轮胎开始旋转");}//具体产品public class ForeignTire implements Tirepublic void rotatSystem.out.println("进口轮胎开始旋转");}```最后,客户端通过具体工厂创建具体产品:```javapublic class Clientpublic static void main(String[] args) AbstractFactory factory = new DomesticFactory(; Car car = factory.createCar(;car.drive(;Tire tire = factory.createTire(;tire.rotate(;factory = new ForeignFactory(;car = factory.createCar(;car.drive(;tire = factory.createTire(;tire.rotate(;}```运行客户端代码输出:```国产汽车开始启动国产轮胎开始旋转进口汽车开始启动进口轮胎开始旋转```通过抽象工厂模式,客户端代码无需关注具体的产品类,只需要通过工厂创建产品即可。
php设计模式之抽象工厂模式
![php设计模式之抽象工厂模式](https://img.taocdn.com/s3/m/74b7395ae55c3b3567ec102de2bd960590c6d9b8.png)
php设计模式之抽象⼯⼚模式抽象⼯⼚模式(Abstact Factory)是⼀种常见的软件设计模式。
该模式为⼀个产品族提供了统⼀的创建接⼝。
当需要这个产品族的某⼀系列的时候,可以为此系列的产品族创建⼀个具体的⼯⼚类。
⼀、意图抽象⼯⼚模式提供⼀个创建⼀系统相关或相互依赖对象的接⼝,⽽⽆需指定它们具体的类【GOF95】⼆、抽象⼯⼚模式结构图三、结合⼀个简单的例⼦了解⽤种蔬菜的例⼦来说明事实,最初的时候,由于规模⼩,只种植⼀种蔬菜,根菜类蔬菜,这个时候由于种植⽅式⽐较简单,采⽤简单⼯⼚模式即可,主要⽬的是让⼯⼈轻松,下达⼯⼚种植即可,但是随着种植⼚的发展以及市场的需求,要增加⼀种蔬菜类型种植了,茎菜,由于茎菜与根菜种植⽅式不⼀致,就需要两个专门的种植⼯⼚来进⾏管理,那么久采⽤⼯⼚模式来管理,⼀个⼯⼚负责⼀种作物的种植,这个时候产品可以理解为仍然在⼀个层次。
但是随着科技的发展,我们逐步要种植转基因与⾮转基因⾷品了,在以前的蔬菜种类上⼜增加了⼀个层次,这个时候⽆法将其作为⼀个层次来解决,所以必须采⽤抽象⼯⼚的⽅式来解决。
我⽤UML图表⽰三种结构:上⾯的UML图很明显的就看出来了,抽象⼯⼚可以创建多个产品类对象,如在种菜⼯⼚中,有种根菜,种茎菜。
⼯⼚模式与抽象⼯⼚模式以及简单⼯⼚模式只有在具体应⽤的时候,分析具体的产品层级,然后选择相应的设计模式。
⽽在每⼀个层次,种菜⼯⼈所关⼼的对象也不⼀样,在简单⼯⼚模式下,⼯⼈要想到种植萝⼘还是⽩菜,在⼯⼚模式下,⼯⼈想到是种植根菜还是茎菜,⽽在抽象⼯⼚模式下,则关⼼种植基因菜还是⾮基因菜四、抽象⼯⼚模式中主要⾓⾊抽象⼯⼚(Abstract Factory)⾓⾊:它声明⼀个创建抽象产品对象的接⼝。
通常以接⼝或抽象类实现,所有的具体⼯⼚类必须实现这个接⼝或继承这个类。
具体⼯⼚(Concrete Factory)⾓⾊:实现创建产品对象的操作。
客户端直接调⽤这个⾓⾊创建产品的实例。
Abstract Factory模式详解及应用场景
![Abstract Factory模式详解及应用场景](https://img.taocdn.com/s3/m/34879b521fd9ad51f01dc281e53a580216fc50b4.png)
Abstract Factory模式详解及应用场景Abstract Factory模式是一种软件设计模式,它是工厂方法模式的升级版。
它的作用是提供一种统一的接口,用来创建一系列相关或相互依赖的对象,而无需指定它们的具体类。
抽象工厂可以看做一种工厂的工厂,它管理着一系列的工厂,每个工厂负责创建一组对象。
下面将详细介绍Abstract Factory的工作原理及应用场景。
一、工作原理Abstract Factory模式分为抽象工厂、具体工厂、抽象产品、具体产品四个部分。
其中,抽象工厂和抽象产品是组成Abstract Factory模式最关键的两部分。
抽象工厂(Abstract Factory):抽象工厂是一个接口,它声明了一组用于创建一系列产品的方法。
每个方法都对应于某一种产品。
具体工厂(Concrete Factory):具体工厂是抽象工厂的子类,它实现了所有在抽象工厂中声明的方法,用于创建具体产品。
抽象产品(Abstract Product):抽象产品是一个接口,它声明了一组用于具体产品的共同属性和方法。
具体产品(Concrete Product):具体产品是实现抽象产品中定义的接口的对象,它通过具体工厂创建。
下面用一个例子来说明Abstract Factory模式的工作原理。
假设在一个电商平台上,有两个商家A和B,他们都销售服装,分别有衣服和裤子两种产品。
要实现Abstract Factory模式,需要先定义抽象产品和抽象工厂。
抽象产品```java// 衣服抽象产品public interface Clothes {public void show();}// 裤子抽象产品public interface Pants {public void show();}```抽象工厂```java// 抽象工厂public interface Factory {public Clothes createClothes();public Pants createPants();}```接下来,定义商家A和B的具体产品和具体工厂。
抽象工厂模式的应用场景
![抽象工厂模式的应用场景](https://img.taocdn.com/s3/m/2b46eb02ef06eff9aef8941ea76e58fafab045e4.png)
抽象工厂模式的应用场景抽象工厂模式是一种常用的设计模式,其主要作用是抽象出一个工厂接口,然后具体的工厂实现基于该接口构建不同的产品。
这种设计模式在实际开发中有着广泛的应用,下面就来详细探讨其在不同场景下的使用情况。
一、Web应用中的抽象工厂模式在Web应用中,抽象工厂模式非常常见。
例如,一个在线咖啡厅网站,其需要实现不同种类的饮品,包括浓缩咖啡、卡布奇诺、拿铁等等。
此时,可以采用抽象工厂模式,将饮品的种类作为产品族,不同种类的饮品则是产品族中的不同产品。
这样,每个饮品可以由一个具体的工厂类来构建,而所有的工厂类都可以基于同一个抽象工厂接口来实现。
二、游戏开发中的抽象工厂模式在游戏开发中,抽象工厂模式同样可以起到重要作用。
例如,一个游戏中需要不同种类的武器和防具,可以将武器和防具视为不同的产品族,每个具体的武器或防具则是产品族中的不同产品。
此时,可以采用抽象工厂模式来构建不同的工厂类,每个工厂类负责创建不同种类的武器或防具。
这样,通过简单的修改工厂类,就可以很容易地扩展游戏的武器和防具系统。
三、操作系统开发中的抽象工厂模式在操作系统开发中,抽象工厂模式也有着广泛的应用。
例如,操作系统中包含多个不同种类的进程调度算法,每个算法都是进程调度算法族中的不同产品。
此时,可以采用抽象工厂模式,将进程调度算法族作为产品族,每个具体的进程调度算法则是产品族中的不同产品。
通过简单的切换不同的工厂类,就可以实现不同的进程调度算法。
总结:抽象工厂模式是一种常用的设计模式,在实际开发中有着广泛的应用。
通过将对象的构造与产品族进行分离,我们可以很容易地扩展系统的功能,同时还可以提高代码的可维护性和可扩展性。
无论是Web应用、游戏开发、还是操作系统开发,抽象工厂模式都可以为我们提供很好的解决方案。
Java设计模式之抽象工厂模式(Abstract
![Java设计模式之抽象工厂模式(Abstract](https://img.taocdn.com/s3/m/a0522dee760bf78a6529647d27284b73f24236da.png)
Java设计模式之抽象⼯⼚模式(Abstract Factory)作为⼯⼚⽅法模式的孪⽣兄弟,相信⼤家对⼯⼚⽅法模式和抽象⼯⼚模式傻傻分不清楚吧。
那么,就让我来拯救⼤家吧!抽象⼯⼚模式定义:所谓抽象⼯⼚模式就是为创建⼀组相关或相互依赖的对象提供⼀个接⼝,⽽且⽆需指定他们的具体类。
类型:创建类模式类图:抽象⼯⼚模式与⼯⼚⽅法模式的区别抽象⼯⼚模式是⼯⼚⽅法模式的升级版本,他⽤来创建⼀组相关或者相互依赖的对象。
他与⼯⼚⽅法模式的区别就在于,⼯⼚⽅法模式针对的是⼀个产品等级结构;⽽抽象⼯⼚模式则是针对的多个产品等级结构。
在编程中,通常⼀个产品结构,表现为⼀个接⼝或者抽象类,也就是说,⼯⼚⽅法模式提供的所有产品都是衍⽣⾃同⼀个接⼝或抽象类,⽽抽象⼯⼚模式所提供的产品则是衍⽣⾃不同的接⼝或抽象类。
在抽象⼯⼚模式中,有⼀个产品族的概念:所谓的产品族,是指位于不同产品等级结构中功能相关联的产品组成的家族。
抽象⼯⼚模式所提供的⼀系列产品就组成⼀个产品族;⽽⼯⼚⽅法提供的⼀系列产品称为⼀个等级结构。
我们拿⽣产汽车的例⼦来说明他们之间的区别。
在上⾯的类图中,两厢车和三厢车称为两个不同的等级结构;⽽2.0排量车和2.4排量车则称为两个不同的产品族。
再具体⼀点,2.0排量两厢车和2.4排量两厢车属于同⼀个等级结构,2.0排量三厢车和2.4排量三厢车属于另⼀个等级结构;⽽2.0排量两厢车和2.0排量三厢车属于同⼀个产品族,2.4排量两厢车和2.4排量三厢车属于另⼀个产品族。
明⽩了等级结构和产品族的概念,就理解⼯⼚⽅法模式和抽象⼯⼚模式的区别了,如果⼯⼚的产品全部属于同⼀个等级结构,则属于⼯⼚⽅法模式;如果⼯⼚的产品来⾃多个等级结构,则属于抽象⼯⼚模式。
在本例中,如果⼀个⼯⼚模式提供2.0排量两厢车和2.4排量两厢车,那么他属于⼯⼚⽅法模式;如果⼀个⼯⼚模式是提供2.4排量两厢车和2.4排量三厢车两个产品,那么这个⼯⼚模式就是抽象⼯⼚模式,因为他提供的产品是分属两个不同的等级结构。
解析抽象工厂设计模式
![解析抽象工厂设计模式](https://img.taocdn.com/s3/m/29ffc546f56527d3240c844769eae009581ba216.png)
解析抽象工厂设计模式抽象工厂设计模式是一种软件架构模式,它将抽象概念与具体实现分离,让实现模块化,易于扩展和维护。
本文将对抽象工厂模式的特点、结构、实现和使用等方面进行解析。
一、特点抽象工厂模式是一种创建型模式,它属于对象的创建模式。
它的主要特点有:1. 分离抽象和具体实现:抽象工厂模式将抽象和具体实现分离,使得客户端能够独立于具体实现,而只是依赖于抽象的接口。
2. 容易扩展和维护:抽象工厂模式的结构简单明了,每个具体工厂只负责生产自己所属的产品族,如果需要添加新的产品族,只需要增加一个新的具体工厂即可,不用修改原有代码。
3. 细粒度的控制:抽象工厂模式与工厂方法模式不同之处,在于它不仅仅可以创建单一的对象,而是可以创建一组相关联的对象,这样就可以实现对对象的更细粒度的控制。
二、结构抽象工厂模式的结构非常简单,一般包括以下四个部分:1. 抽象工厂:提供了一个接口,用来创建一组相关或者相互依赖的对象。
2. 具体工厂:实现了抽象工厂中所定义的接口,用来创建具体的产品对象。
3. 抽象产品:定义了产品的抽象属性和方法。
4. 具体产品:实现了抽象产品接口中定义的方法,是一种具体的实现。
三、实现下面以一个简单的例子来说明抽象工厂模式的使用:假如我们要开发一个游戏,游戏中有泰坦、魔法师等不同种类的角色,这些角色都有相应的武器和装备,我们可以通过抽象工厂模式来实现这个游戏。
首先我们定义角色的抽象类Role,它有两个子类Titan和Wizard,它们分别实现了自己独特的属性和行为。
```javaabstract class Role {public abstract void attack();}class Titan extends Role {public void attack() {System.out.println("Titan is attacking with axe!");}}class Wizard extends Role {public void attack() {System.out.println("Wizard is attacking with magic!");}}```接下来我们定义武器的抽象类Weapon,它有两个子类Axe和Magic,它们分别是角色Titan和Wizard的武器。
23种设计模式之——抽象工厂模式
![23种设计模式之——抽象工厂模式](https://img.taocdn.com/s3/m/126d1226e3bd960590c69ec3d5bbfd0a7956d5dd.png)
23种设计模式之——抽象⼯⼚模式什么是抽象⼯⼚模式?提供⼀个创建⼀系列相关或相互依赖对象的接⼝,⽽⽆需指定它们具体的类。
抽象⼯⼚模式有哪些优点?1、最⼤的好处便是易于交换产品系列,由于具体⼯⼚类,在⼀个应⽤中只需要在初始化的时候出现⼀次,这就使得改变⼀个应⽤的具体⼯⼚变得⾮常容易,它只需要改变具体⼯⼚即可使⽤不同产品配置。
2、它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接⼝操作实例,产品的具体类名也被具体⼯⼚的实现分离,不会出现在客户代码中。
如果项⽬使⽤的是MySQL数据,现在如果需要更换为Oracle数据,为了灵活更换数据库,如何设计程序呢?接下来通过抽象⼯⼚模式模仿数据访问程序。
抽象⼯⼚模式实现:构建两张数据库表的对应类,只声明,不做任何操作。
Name类:Type类:为两张表创建相应的实现类:IUser接⼝,⽤于客户端访问,解除与具体数据库访问的耦合:IType接⼝,⽤于客户端访问,解除与具体数据库访问的耦合:MySQLUser类,⽤于访问MySQL的User表:OracleUser类,⽤于访问Oracle的User表:同理创建相应的MySQL和Oracle数据库的Type表。
MySQLType类,⽤于访问MySQL的Type表:OracleType类,⽤于访问Oracle的Type表:接下来再让我们构建⼀个IFactory接⼝,定义⼀个访问User表对象和Type对象的抽象的⼯⼚接⼝。
MySQLFactory类,实现IFactory接⼝,实例化MySQLUser和MySQLType。
OracleFactory类,实现IFactory接⼝,实例化OracleUser和OralceType。
客户端代码:只需确认实例化哪⼀个数据库访问对象给factory。
运⾏结果如下:只需要更改IFactory factory = new MySQLFactory() 为IFactory factory = new OracleFactory() ,就实现了数据库访问的切换了。
对设计模式的总结之工厂方法模式和抽象工厂模式
![对设计模式的总结之工厂方法模式和抽象工厂模式](https://img.taocdn.com/s3/m/5cb399eb760bf78a6529647d27284b73f24236f9.png)
对设计模式的总结之⼯⼚⽅法模式和抽象⼯⼚模式前⾔⾯向对象编程追求的本质-提⾼扩展性、可维护性、灵活性和复⽤性。
合理利⽤⾯向对象6个原则,能够很好的达到要求。
如何利⽤好就是⾄关重要的了,前⼈总结了23+个设计模式能够让初学者更容易学到其中的精髓,本⽂就说说我对本⼈对⼯⼚⽅法模式和抽象⼯⼚模式的见解。
设计模式链接1.2.3.4.⼯⼚⽅法模式与抽象⼯⼚模式⼯⼚⽅法模式在过去,许多⼤型项⽬都是⼀个整体,各个模块都⽤⼀套技术完成,部署的时候也是每台服务器上都是整套部署。
每次版本升级都需要将整个项⽬全部升级完毕才能够重新部署。
如果是迭代N年,⾮常庞⼤的项⽬,可能⼀次版本升级就会弄残⼀堆研发。
为了使版本升级更灵活,开发技术不局限⼀套,微服务就诞⽣了--将⼀个⼤系统拆分成N个单独功能的⼦系统,分开部署在不同服务器,版本升级也不需要整套系统⼀起升级。
现在某个⼦系统需要增加⼀个与N个游戏⼦系统交互的功能,⽽且后期还会不断增加新的游戏⼦系统。
考虑到后期会增加游戏⼦系统,⽤简单⼯⼚除了增加新的交互类,还需要更改⼯⼚⽅法,破坏了开放封闭原则。
那还有什么更好⼀些的办法吗?可以考虑⼯⼚⽅法模式:定义⼀个创建产品对象的⼯⼚抽象类(抽象类或接⼝),利⽤继承的好处,将具体的创建⼯作"延时"到⼦类进⾏。
核⼼⼯⼚类不再负责产品的创建,这样核⼼类成为⼀个抽象⼯⼚⾓⾊,仅负责具体⼯⼚⼦类必须实现的基类,这样进⼀步抽象化的好处是使得⼯⼚⽅法模式可以使系统在不修改具体⼯⼚⾓⾊的情况下引进新的产品。
基本⽤法1.///<summary>///抽象⼯⼚⾓⾊///</summary>public abstract class FuncFactory{///<summary>///⽣成产品的对象抽象///</summary>///<returns></returns>public abstract GameInteraction Create();}public class AGameInteractionFactory : FuncFactory{///<summary>///实现具体产品⽣产(⽣成具体交互类实例)///</summary>///<returns></returns>public override GameInteraction Create(){return new AGameInteraction();}}public class BGameInteractionFactory : FuncFactory{///<summary>///实现具体产品⽣产(⽣成具体交互类实例)///</summary>///<returns></returns>public override GameInteraction Create(){return new BGameInteraction();}}///<summary>///与游戏服务端交互抽象///</summary>public abstract class GameInteraction{///<summary>///与游戏交互⽅法(都需要和游戏端交互)///</summary>///<param name="sloginName">账号</param>///<returns></returns>public abstract string InfoInteaction(string sloginName);}public class AGameInteraction: GameInteraction{///<summary>///与游戏A交互⽅法///</summary>///<param name="sloginName">账号</param>///<returns></returns>public override string InfoInteaction(string sloginName){return sloginName+"通过TCP/IP⽅式与GameA具体交互逻辑...";}}public class BGameInteraction : GameInteraction{///<summary>///与游戏B交互⽅法///</summary>///<param name="sloginName">账号</param>///<returns></returns>public override string InfoInteaction(string sloginName){return sloginName+"通过HTTP⽅式与GameB具体交互逻辑...";}}客户端使⽤://获取程序集路径string assemblyName = AppDomain.CurrentDomain.BaseDirectory+ "ObjectOriented_Tools.dll";//反射AGameInteractionFactory⽣成实例,赋值给FuncFactory//FuncFactory reflect = (FuncFactory)Assembly.LoadFile(assemblyName).CreateInstance("ObjectOriented_Tools.FuncFactory.AGameInteractionFactory");FuncFactory reflect = (FuncFactory)Assembly.Load("ObjectOriented_Tools").CreateInstance("ObjectOriented_Tools.FuncFactory.AGameInteractionFactory");GameInteraction gameInteraction = reflect.Create();//创建具体交互实例txt_description.Text ="反射操作:\r\n"+ Inteaction("铁锅盖")+ "\r\n"; //交互//选择具体⼯⼚实例化后,赋值给⼯⼚基类FuncFactory rct = new BGameInteractionFactory();GameInteraction interaction = rct.Create();//创建具体交互实例txt_description.Text += "⼀般操作:\r\n" + Inteaction("铁锅盖"); //交互View Code总结优缺点:1、符合⾯向对象编程的开放封闭原则,增加新的产品,只需要增加新的⼯⼚类即可(对扩展开放),对任何产品的增加或修改,不会影响其它⼯⼚类和产品类(对修改封闭);2、相对简单⼯⼚模式,产品多的时候,系统中的类会成倍增加,造成系统不简洁,增加了⼯⼚类的创建。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
•概述在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时由于需求的变化,往往存在着更多系列对象的创建工作。
怎么应对这种变化?怎么绕过常规的对象的创建方法(new),提供一种“封装机制”来避免客户程式和这种“多系列具体对象创建工作”的紧耦合?这就是我们要说的抽象工厂模式。
意图提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。
模型图逻辑模型:物理模型:生活中的例子抽象工厂的目的是要提供一个创建一系列相关或相互依赖对象的接口,而不必指定他们具体的类。
这种模式能汽车制造厂所使用的金属冲压设备中找到。
这种冲压设备能制造汽车车身部件。
同样的机械用于冲压不同的车型的右边车门、左边车门、右前挡泥板、左前挡泥板和引擎罩等等。
通过使用转轮来改动冲压盘,这个机械产生的具体类能在三分钟内改动。
抽象工厂之新解虚拟案例中国企业需要一项简单的财务计算:每月月底,财务人员要计算员工的工资。
员工的工资= (基本工资+ 奖金- 个人所得税)。
这是个放之四海皆准的运算法则。
为了简化系统,我们假设员工基本工资总是4000美金。
中国企业奖金和个人所得税的计算规则是:奖金= 基本工资(4000) * 10%个人所得税= (基本工资+ 奖金) * 40%我们目前要为此构建一个软件系统(代号叫Softo),满足中国企业的需求。
案例分析奖金(Bonus)、个人所得税(Tax)的计算是Softo系统的业务规则(Service)。
工资的计算(Calculator)则调用业务规则(Service)来计算员工的实际工资。
工资的计算作为业务规则的前端(或客户端Client)将提供给最终使用该系统的用户(财务人员)使用。
针对中国企业为系统建模根据上面的分析,为Softo系统建模如下:则业务规则Service类的代码如下:1using System;23namespace ChineseSalary4{5 /**//// <summary>6 /// 公用的常量7 /// </summary>8 public class Constant9 {10 public static double BASE_SALARY = 4000;11 }12}1using System;23namespace ChineseSalary4{5 /**//// <summary>6 /// 计算中国个人奖金7 /// </summary>8 public class ChineseBonus9 {10 public double Calculate()11 {12 return Constant.BASE_SALARY * 0.1;13 }14 }15}16客户端的调用代码:1using System;23namespace ChineseSalary4{5 /**//// <summary>6 /// 计算中国个人所得税7 /// </summary>8 public class ChineseTax9 {10 public double Calculate()11 {12 return (Constant.BASE_SALARY + (Constant.BASE_SALARY * 0.1)) * 0.4;13 }14 }15}16运行程式,输入的结果如下:Chinese Salary is:2640针对美国企业为系统建模为了拓展国际市场,我们要把该系统移植给美国公司使用。
美国企业的工资计算同样是: 员工的工资= 基本工资+ 奖金-个人所得税。
不过他们的奖金和个人所得税的计算规则不同于中国企业:美国企业奖金和个人所得税的计算规则是:奖金= 基本工资* 15 %个人所得税= (基本工资* 5% + 奖金* 25%)根据前面为中国企业建模经验,我们仅仅将ChineseTax、ChineseBonus修改为AmericanTax、AmericanBonus。
修改后的模型如下:则业务规则Service类的代码如下:1using System;23namespace AmericanSalary4{5 /**//// <summary>6 /// 公用的常量7 /// </summary>8 public class Constant9 {10 public static double BASE_SALARY = 4000;11 }12}131using System;23namespace AmericanSalary4{5 /**//// <summary>6 /// 计算美国个人奖金7 /// </summary>8 public class AmericanBonus9 {10 public double Calculate()11 {12 return Constant.BASE_SALARY * 0.1;13 }14 }15}161using System;23namespace AmericanSalary4{5 /**//// <summary>6 /// 计算美国个人所得税7 /// </summary>8 public class AmericanTax9 {10 public double Calculate()11 {12 return (Constant.BASE_SALARY + (Constant.BASE_SALARY * 0.1)) * 0.4;13 }14 }15}16客户端的调用代码:12using System;34namespace AmericanSalary5{6 /**//// <summary>7 /// 客户端程式调用8 /// </summary>9 public class Calculator10 {11 public static void Main(string[] args)12 {13 AmericanBonus bonus = new AmericanBonus();14 double bonusValue = bonus.Calculate();1516 AmericanTax tax = new AmericanTax();17 double taxValue = tax.Calculate();1819 double salary = 4000 + bonusValue - taxValue;2021 Console.WriteLine("American Salary is:" + salary);22 Console.ReadLine();23 }24 }25}26运行程式,输入的结果如下:American Salary is:2640整合成通用系统让我们回顾一下该系统的发展历程:最初,我们只考虑将Softo系统运行于中国企业。
但随着MaxDO公司业务向海外拓展,MaxDO需要将该系统移植给美国使用。
移植时,MaxDO不得不抛弃中国企业的业务规则类ChineseTax和ChineseBonus,然后为美国企业新建两个业务规则类: AmericanTax,AmericanBonus。
最后修改了业务规则调用Calculator类。
结果我们发现:每当Softo系统移植的时候,就抛弃原来的类。
目前,如果中国联想集团要购买该系统,我们不得不再次抛弃AmericanTax,AmericanBonus,修改回原来的业务规则。
一个能即时想到的做法就是在系统中保留所有业务规则模型,即保留中国和美国企业工资运算规则。
通过保留中国企业和美国企业的业务规则模型,如果该系统在美国企业和中国企业之间转换时,我们仅仅需要修改Caculator 类即可。
让移植工作更简单前面系统的整合问题在于:当系统在客户在美国和中国企业间转换时仍然需要修改Caculator代码。
一个维护性良好的系统应该遵循“开闭原则”。
即:封闭对原来代码的修改,开放对原来代码的扩展(如类的继承,接口的实现)我们发现不论是中国企业还是美国企业,他们的业务运规则都采用同样的计算接口。
于是非常自然地想到建立两个业务接口类Tax,Bonus,然后让AmericanTax、AmericanBonus和ChineseTax、ChineseBonus分别实现这两个接口,据此修正后的模型如下:此时客户端代码如下:12using System;34namespace InterfaceSalary5{6 /**//// <summary>7 /// 客户端程式调用8 /// </summary>9 public class Calculator10 {11 public static void Main(string[] args)12 {13 Bonus bonus = new ChineseBonus();14 double bonusValue = bonus.Calculate();1516 Tax tax = new ChineseTax();17 double taxValue = tax.Calculate();1819 double salary = 4000 + bonusValue - taxValue;2021 Console.WriteLine("Chinaese Salary is:" + salary);22 Console.ReadLine();23 }24 }25}26为业务规则增加工厂方法然而,上面增加的接口几乎没有解决所有问题,因为当系统的客户在美国和中国企业间转换时Caculator代码仍然需要修改。
只不过修改少了两处,不过仍然需要修改ChineseBonus,ChineseTax部分。
致命的问题是:我们需要将这个移植工作转包给一个叫Hippo的软件公司。
由于版权问题,我们并未提供Softo系统的源码给Hippo公司,因此Hippo公司根本无法修改Calculator,导致实际上移植工作无法进行。
为此,我们考虑增加一个工具类(命名为Factory),代码如下:1using System;23namespace FactorySalary4{5 /**//// <summary>6 /// Factory类7 /// </summary>8 public class Factory9 {10 public Tax CreateTax()11 {12 return new ChineseTax();13 }1415 public Bonus CreateBonus()16 {17 return new ChineseBonus();18 }19 }20}21修改后的客户端代码:12using System;34namespace FactorySalary5{6 /**//// <summary>7 /// 客户端程式调用8 /// </summary>9 public class Calculator10 {11 public static void Main(string[] args)12 {13 Bonus bonus = new Factory().CreateBonus();14 double bonusValue = bonus.Calculate();1516 Tax tax = new Factory().CreateTax();17 double taxValue = tax.Calculate();1819 double salary = 4000 + bonusValue - taxValue;2021 Console.WriteLine("Chinaese Salary is:" + salary);22 Console.ReadLine();23 }24 }25}26不错,我们解决了一个大问题,设想一下:当该系统从中国企业移植到美国企业时,我们目前需要做什么?答案是: 对于Caculator类我们什么也不用做。