单利模式 工厂模式
时间: 2023-10-11 11:12:04 浏览: 52
单例模式和工厂模式是两种常见的设计模式。
单例模式是一种保证一个类只有一个实例对象的创建方式。它通过限制类的实例化过程,使得在程序运行期间只存在一个实例对象。这样可以避免多次创建相同对象,节省了系统资源。单例模式通常使用一个静态方法或者全局变量来提供对唯一实例的访问。
工厂模式是一种创建对象的设计模式,它提供了一个统一的接口来创建类的实例,而不需要暴露对象的具体实现细节。工厂模式通过定义一个共同的接口或抽象类作为对象的创建接口,然后由具体的工厂类来实现这个接口并创建具体的对象。这样可以使得客户端代码与具体对象的创建过程解耦,提高了程序的灵活性和可维护性。
总结起来,单例模式主要解决的是如何在整个系统中保持唯一实例的问题,而工厂模式主要解决的是如何统一创建对象的过程,隐藏具体对象创建细节。它们都是常见的设计模式,可以在软件开发中广泛应用。
相关问题
C++面向对象的工厂方法模式demo
### 回答1:
下面是一个使用 C 语言实现面向对象的工厂方法模式的简单示例:
```
#include <stdio.h>
#include <stdlib.h>
typedef struct Product Product;
struct Product {
void (*use)(Product*);
};
typedef struct ConcreteProductA ConcreteProductA;
struct ConcreteProductA {
Product product;
int concrete_a_data;
};
void concrete_product_a_use(Product* product) {
ConcreteProductA* concrete_product_a = (ConcreteProductA*) product;
printf("ConcreteProductA use, concrete_a_data = %d\n", concrete_product_a->concrete_a_data);
}
typedef struct ConcreteProductB ConcreteProductB;
struct ConcreteProductB {
Product product;
int concrete_b_data;
};
void concrete_product_b_use(Product* product) {
ConcreteProductB* concrete_product_b = (ConcreteProductB*) product;
printf("ConcreteProductB use, concrete_b_data = %d\n", concrete_product_b->concrete_b_data);
}
typedef struct Creator Creator;
struct Creator {
Product* (*factory_method)();
};
typedef struct ConcreteCreatorA ConcreteCreatorA;
struct ConcreteCreatorA {
Creator creator;
};
Product* concrete_creator_a_factory_method() {
ConcreteProductA* concrete_product_a = (ConcreteProductA*) malloc(sizeof(ConcreteProductA));
concrete_product_a->product.use = concrete_product_a_use;
concrete_product_a->concrete_a_data = rand() % 100;
return (Product*) concrete_product_a;
}
typedef struct ConcreteCreatorB ConcreteCreatorB;
struct ConcreteCreatorB {
Creator creator;
};
Product* concrete_creator_b_factory_method() {
ConcreteProductB* concrete_product_b = (ConcreteProductB*) malloc(sizeof(ConcreteProductB));
concrete_product_b->product.use = concrete_product_b_use;
concrete_product_b->concrete_b_data = rand() % 100;
return (Product*) concrete_product_b;
}
int main() {
Creator* creator = (Creator*) malloc(sizeof(ConcreteCreatorA));
creator->factory_method = concrete_creator_a_factory_method;
Product* product = creator->factory_method();
product->use(product);
free(product);
creator = (Creator*) malloc(sizeof(ConcreteCreatorB));
creator->factory_method = concrete_creator_b_factory_method;
product = creator->factory_method();
product->use(product);
free(product);
free(creator);
### 回答2:
面向对象的工厂方法模式是一种创建型设计模式,它将对象的创建委托给工厂类,实现了对象的创建与使用的分离,可以灵活地添加新的产品类型而无需修改客户端代码。
以一个简单的图形绘制工具为例,我们可以使用工厂方法模式实现对不同图形对象的创建。
首先,我们定义一个抽象的图形类,包含绘制方法draw():
class Shape {
public abstract void draw();
}
然后,定义不同的具体图形类,继承自抽象图形类:
class Rectangle extends Shape {
public void draw() {
// 绘制矩形的具体实现
}
}
class Circle extends Shape {
public void draw() {
// 绘制圆形的具体实现
}
}
接下来,我们定义一个抽象的图形工厂类,包含创建图形对象的方法createShape():
class ShapeFactory {
public abstract Shape createShape();
}
然后,定义不同的具体图形工厂类,继承自抽象图形工厂类:
class RectangleFactory extends ShapeFactory {
public Shape createShape() {
return new Rectangle();
}
}
class CircleFactory extends ShapeFactory {
public Shape createShape() {
return new Circle();
}
}
最后,我们可以在客户端代码中通过具体的工厂类创建具体的图形对象并调用相应的方法:
ShapeFactory factory = new RectangleFactory();
Shape shape = factory.createShape();
shape.draw();
这样,通过工厂方法模式,我们可以实现对不同图形对象的创建和使用的解耦,从而提高了系统的扩展性和灵活性。
### 回答3:
工厂方法模式是一种创建型设计模式,用于解耦具体对象的创建和使用。在面向对象的编程中,通常需要通过实例化具体的对象来完成某个功能,这会导致代码耦合度高、可维护性差。而工厂方法模式通过定义一个抽象工厂类,让子类具体实现创建对象的方法,以达到解耦的效果。
下面以一个计算器为例来演示工厂方法模式的使用。
首先,我们定义一个抽象的计算器接口Calculator,其中包含了两个方法:add和subtract。
接着,我们创建两个具体类CalculatorAdd和CalculatorSubtract,它们分别实现了Calculator接口,并分别实现了add和subtract方法,用于进行加法和减法运算。
然后,我们创建一个抽象工厂类CalculatorFactory,其中包含一个创建计算器的抽象方法createCalculator。
最后,我们创建两个具体工厂类CalculatorAddFactory和CalculatorSubtractFactory,它们分别实现了CalculatorFactory接口,并实现了createCalculator方法,分别用来创建加法计算器和减法计算器的对象。
这样,当我们需要使用计算器时,只需通过具体工厂类创建对应的计算器对象,并直接使用其方法进行计算,无需关心具体对象的创建细节。
工厂方法模式可以将对象的创建和使用分离开来,提高代码的可维护性和可扩展性。当需要新增一种计算器时,只需创建一个新的具体工厂类和计算器类,并通过扩展抽象工厂类和接口来完成,无需修改已有的代码。同时,也方便进行单元测试和代码的复用。
总之,工厂方法模式是一种常用的设计模式,在面向对象的编程中具有重要的应用价值。
使用Java语言编写程序,使用五种设计模式,不使用简单工厂和单例模式,可使用装饰模式或者其他模式,必须使用五种模式。题目:XX游戏抽卡,需要有概率公⽰说明(屏幕输出查看),抽卡物品可以是⼈物或装备。要求⾄少有三个不同等级的物品(⽐如3星,4星,5星),要在代码中写出不同星级物品的名字 ⽰例:抽卡有单抽和10连,⼀般为3星,4星的概率8%,5星概率1%,10连必出4星,抽80 次没出5星必出5星。要使用命令行输入抽奖次数,输出抽卡结果。用java代码展示结果
在这个游戏中,我们将使用以下五种设计模式:工厂方法模式、策略模式、装饰者模式、观察者模式和模板方法模式。以下是代码示例:
首先,我们需要定义一个抽卡物品的接口,包括获取名称和星级的方法:
```java
public interface GachaItem {
String getName();
int getStars();
}
```
然后,我们可以实现这个接口来创建不同星级的物品:
```java
public class ThreeStarItem implements GachaItem {
@Override
public String getName() {
return "三星物品";
}
@Override
public int getStars() {
return 3;
}
}
public class FourStarItem implements GachaItem {
@Override
public String getName() {
return "四星物品";
}
@Override
public int getStars() {
return 4;
}
}
public class FiveStarItem implements GachaItem {
@Override
public String getName() {
return "五星物品";
}
@Override
public int getStars() {
return 5;
}
}
```
接下来,我们将使用工厂方法模式来创建不同星级的物品。我们需要定义一个抽象的抽卡工厂类,并在其中声明一个创建抽卡物品的方法:
```java
public abstract class GachaFactory {
public abstract GachaItem createGachaItem();
}
```
然后,我们可以实现这个工厂类来创建不同星级的物品:
```java
public class ThreeStarItemFactory extends GachaFactory {
@Override
public GachaItem createGachaItem() {
return new ThreeStarItem();
}
}
public class FourStarItemFactory extends GachaFactory {
@Override
public GachaItem createGachaItem() {
return new FourStarItem();
}
}
public class FiveStarItemFactory extends GachaFactory {
@Override
public GachaItem createGachaItem() {
return new FiveStarItem();
}
}
```
现在,我们可以使用工厂方法模式来创建不同星级的物品了:
```java
GachaFactory factory = new ThreeStarItemFactory();
GachaItem item = factory.createGachaItem();
System.out.println("抽到了:" + item.getName() + ",星级为:" + item.getStars());
```
下一步,我们将使用策略模式来定义不同抽卡方式的概率。我们需要定义一个抽卡概率接口,并在其中声明一个获取概率的方法:
```java
public interface GachaProbability {
double getProbability();
}
```
然后,我们可以实现这个接口来创建不同抽卡方式的概率:
```java
public class SingleGachaProbability implements GachaProbability {
@Override
public double getProbability() {
return 0.08;
}
}
public class TenGachaProbability implements GachaProbability {
@Override
public double getProbability() {
return 1.0;
}
}
```
现在,我们可以使用策略模式来计算不同抽卡方式的概率了:
```java
GachaProbability probability = new SingleGachaProbability();
double p = probability.getProbability();
```
接下来,我们将使用装饰者模式来实现抽卡结果的输出。我们需要定义一个抽卡结果接口,并在其中声明一个输出结果的方法:
```java
public interface GachaResult {
void printResult();
}
```
然后,我们可以实现这个接口来输出不同的抽卡结果:
```java
public class ThreeStarGachaResult implements GachaResult {
private GachaResult result;
public ThreeStarGachaResult(GachaResult result) {
this.result = result;
}
@Override
public void printResult() {
result.printResult();
System.out.println("获得了一个三星物品!");
}
}
public class FourStarGachaResult implements GachaResult {
private GachaResult result;
public FourStarGachaResult(GachaResult result) {
this.result = result;
}
@Override
public void printResult() {
result.printResult();
System.out.println("获得了一个四星物品!");
}
}
public class FiveStarGachaResult implements GachaResult {
private GachaResult result;
public FiveStarGachaResult(GachaResult result) {
this.result = result;
}
@Override
public void printResult() {
result.printResult();
System.out.println("获得了一个五星物品!");
}
}
```
现在,我们可以使用装饰者模式来输出抽卡结果了:
```java
GachaResult result = new ThreeStarGachaResult(new FourStarGachaResult(new FiveStarGachaResult(null)));
result.printResult();
```
接下来,我们将使用观察者模式来实现概率公示的输出。我们需要定义一个观察者接口,并在其中声明一个更新概率的方法:
```java
public interface GachaObserver {
void update(double probability);
}
```
然后,我们可以实现这个接口来创建不同的观察者:
```java
public class SingleGachaObserver implements GachaObserver {
@Override
public void update(double probability) {
System.out.println("单抽概率为:" + probability);
}
}
public class TenGachaObserver implements GachaObserver {
@Override
public void update(double probability) {
System.out.println("十连概率为:" + probability);
}
}
```
现在,我们可以使用观察者模式来输出概率公示了:
```java
GachaObserver singleObserver = new SingleGachaObserver();
GachaObserver tenObserver = new TenGachaObserver();
singleProbability.addObserver(singleObserver);
tenProbability.addObserver(tenObserver);
```
最后,我们将使用模板方法模式来实现抽卡流程的控制。我们需要定义一个抽卡模板类,并在其中声明一个抽卡方法:
```java
public abstract class GachaTemplate {
private int times;
public GachaTemplate(int times) {
this.times = times;
}
public void gacha() {
GachaProbability probability = getGachaProbability();
GachaFactory factory = getGachaFactory();
for (int i = 0; i < times; i++) {
double p = probability.getProbability();
GachaItem item = factory.createGachaItem();
GachaResult result = getGachaResult(item);
if (p >= 0.01) {
result.printResult();
} else {
GachaResult fiveStarResult = new FiveStarGachaResult(result);
fiveStarResult.printResult();
break;
}
}
}
public abstract GachaProbability getGachaProbability();
public abstract GachaFactory getGachaFactory();
public abstract GachaResult getGachaResult(GachaItem item);
}
```
然后,我们可以实现这个模板类来控制不同的抽卡流程:
```java
public class SingleGachaTemplate extends GachaTemplate {
public SingleGachaTemplate(int times) {
super(times);
}
@Override
public GachaProbability getGachaProbability() {
return new SingleGachaProbability();
}
@Override
public GachaFactory getGachaFactory() {
double p = Math.random();
if (p < 0.6) {
return new ThreeStarItemFactory();
} else if (p < 0.96) {
return new FourStarItemFactory();
} else {
return new FiveStarItemFactory();
}
}
@Override
public GachaResult getGachaResult(GachaItem item) {
if (item.getStars() == 3) {
return new ThreeStarGachaResult(null);
} else if (item.getStars() == 4) {
return new FourStarGachaResult(null);
} else {
return new FiveStarGachaResult(null);
}
}
}
public class TenGachaTemplate extends GachaTemplate {
public TenGachaTemplate(int times) {
super(times);
}
@Override
public GachaProbability getGachaProbability() {
return new TenGachaProbability();
}
@Override
public GachaFactory getGachaFactory() {
return new FourStarItemFactory();
}
@Override
public GachaResult getGachaResult(GachaItem item) {
if (item.getStars() == 4) {
return new FourStarGachaResult(null);
} else {
return new FiveStarGachaResult(null);
}
}
}
```
现在,我们可以使用模板方法模式来控制抽卡流程了:
```java
GachaTemplate template = new SingleGachaTemplate(10);
template.gacha();
```