『设计模式』撩妹秘籍竟是使用设计模式的抽象工厂模式
引入:可以跳过
如果存在一部撩妹的手机,加上一个后宫,请问你该怎么做?
砸了手机,跟老婆孩子好好过日子,本篇文章到此结束!
我们强行分析一波,假设存在一位叫做志强的男主(没有在含沙射影)没有砸掉手机,首先每个姑娘都会有名字,防止太多认错了。
我们把维系关系简单的分成:暧昧–闲聊–约(当然是逛商场啦,别想太多) 对于不同的妹子,肯定采用了不同的暧昧,闲聊,约的方式来俘获他么芳心。
如果重构志强与后宫的关系,那么你会发现志强的撩妹方式,直接和名字挂钩,对于每一位姑娘的暧昧–闲聊–约可以看作是一个产品族。志强在某一时刻可以同时存在多个姑娘,但是在某一时刻只能消费一位姑娘(指的逛商场,且不包含多人运动的情况),那么也就是说志强在某一时刻只消费某一产品族。这就是赤裸裸的抽象工厂模式!
我们以一台计算机主机为例,机箱,主板,cpu,内存条,显卡,硬盘是构成一台主机的组成部分,这里我们有Dell一套,华硕一套,惠普一套,那么每一套就是产品族,因为他们包含了所有组成的他们的产品种类,这就是抽象工厂模式。(打钱!!!)
抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
意图:
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
主要解决:
主要解决接口选择的问题。
何时使用:
- 希望一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节时。
- 一个系统有多于一个的产品族,而系统只消费其中某一产品族
角色:
-
抽象工厂(Abstract Factory)角色:
担任这个角色的是工厂方法模式的核心,它是与应用系统商业逻辑无关的。 -
具体工厂(Concrete Factory)角色:
这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对
象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的 -
抽象产品(Abstract Product)角色:
担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。 -
具体产品(Concrete Product)角色:
抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。
这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。
厂商看到打钱!😂
与工厂模式的区别:
- AbstractFactory模式是为创建一组(有多类)相关或依赖的对象提供创建接口
- Factory模式是为一类对象提供创建接口
优缺点:
“开放-封闭”原则要求系统对扩展开放,对修改封闭。通过扩展达到增强其功能的目的。对于涉及到多个产品族与多个产品等级结构的系统,其功能增加包括两方面:
-
增加产品族:Abstract Factory很好的支持了"开放-封闭开放-封闭"原则
-
增加新产品的等级结构:需要修改所有的工厂角色,没有很好支持“开放-封闭”原则。
-
综合起来,抽象工厂模式以一种倾斜的方式支持增加新的产品,它为新产品族的增加提供方便,而不能为新的产品等级结构的增加提供这样的方便。
当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。
解决方案: 反射
UML图
实现
UML类似上面的,在重新给出一遍。
IProductA
package AbstractFactory;
public interface IProductA {
//每个产品共有的方法
public void shareMethod();
// 每个产品相同方法,不同实现
public void doSomething();
}
IProductB
package AbstractFactory;
public interface IProductB {
//每个产品共有的方法
public void shareMethod() ;
// 每个产品相同方法,不同实现
public void doSomething();
}
ProductA1
package AbstractFactory;
public class ProductA1 implements IProductA {
public void doSomething() {
System.out.println("我是产品A1");
}
@Override
public void shareMethod() {
// TODO Auto-generated method stub
}
}
ProductA2
package AbstractFactory;
public class ProductA2 implements IProductA {
public void doSomething() {
System.out.println("我是产品A2");
}
@Override
public void shareMethod() {
// TODO Auto-generated method stub
}
}
ProductB1
package AbstractFactory;
public class ProductB1 implements IProductB {
public void doSomething() {
System.out.println("我是产品B1");
}
@Override
public void shareMethod() {
// TODO Auto-generated method stub
}
}
ProductB2
package AbstractFactory;
public class ProductB2 implements IProductB {
public void doSomething() {
System.out.println("我是产品B2");
}
@Override
public void shareMethod() {
// TODO Auto-generated method stub
}
}
ICreator
package AbstractFactory;
public interface ICreator {
//创建A产品
public IProductA createProductA();
//创建B产品
public IProductB createProductB();
}
Creator1
package AbstractFactory;
public class Creator1 implements ICreator {
public IProductA createProductA() {
return new ProductA1();
}
public IProductB createProductB() {
return new ProductB1();
}
}
Creator2
package AbstractFactory;
public class Creator2 implements ICreator {
public IProductA createProductA() {
return new ProductA2();
}
public IProductB createProductB() {
return new ProductB2();
}
}
Client
package AbstractFactory;
public class Client {
public static void main(String[] args) {
//定义出两个工厂
ICreator creator1 = new Creator1();
ICreator creator2 = new Creator2();
//产生A1对象
IProductA a1 = creator1.createProductA();
//产生A2对象
IProductA a2 = creator2.createProductA();
//产生B1对象
IProductB b1 = creator1.createProductB();
//产生B2对象
IProductB b2 = creator2.createProductB();
a1.doSomething();
a2.doSomething();
b1.doSomething();
b2.doSomething();
}
}
运行结果
!!!使用反射加配置文件解耦实现上述过程
去掉所有Creator相关,其余不变。
加上以下内容:
package AbstractFactory;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.Properties;
public class Reflect_Creator {
private static String Type = null;
public void init() {
Properties pro = new Properties();
ClassLoader classLoader = DataAccess.class.getClassLoader();
InputStream is = classLoader.getResourceAsStream("DataBaseSetting.properties");
try {
pro.load(is);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("初始化失败,请检查配置文件");
}
Type = pro.getProperty("Type");
}
public IProductA createProductA() throws Exception {
Class<?> cls = Class.forName(Type+"1");
Constructor<?> cs=cls.getConstructor( );
Object re= cs.newInstance();
return (IProductA) re;
}
//创建B产品
public IProductB createProductB() throws Exception {
Class<?> cls = Class.forName(Type+"2");
Constructor<?> cs=cls.getConstructor( );
Object re= cs.newInstance();
return (IProductB) re;
}
}
package AbstractFactory;
public class Client {
public static void main(String[] args) throws Exception {
Reflect_Creator.init();
IProductA A1=Reflect_Creator.createProductA();
IProductB B1=Reflect_Creator.createProductB();
}
}
老有人私信我,说我博客表情包花里胡哨的,我想说,我不放表情包,部分小伙伴不一定能看完整篇文章,以后会减少出现,但一定不会缺席。😂
写在最后:
我叫风骨散人,名字的意思是我多想可以不低头的自由生活
,可现实却不是这样。家境贫寒,总得向这个世界低头,所以我一直在奋斗,想改变我的命运
给亲人好的生活,希望同样被生活绑架的你
可以通过自己的努力改变现状,深知成年人的世界里没有容易二字。目前是一名在校大学生,预计考研,热爱编程,热爱技术,喜欢分享,知识无界,希望我的分享可以帮到你!
如果有什么想看的,可以私信我,如果在能力范围内,我会发布相应的博文!
感谢大家的阅读!😘你的点赞、收藏、关注是对我最大的鼓励!