工厂模式

工厂模式

#0 冷锋SJ记忆

son***e_xuan@126.com

152使用反射机制可以解决每次增加一个产品时,都需要增加一个对象实现工厂的缺点

public class ShapeFactory {

public static Object getClass(Class clazz) {

Object obj = null;

try {

obj = Class.forName(clazz.getName()).newInstance();

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (InstantiationException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

return obj;

}

}

使用的使用采用强制转换

Rectangle rect = (Rectangle) ShapeFactory.getClass(Rectangle.class);

rect.draw();

Square square = (Square) ShapeFactory.getClass(Square.class);

square.draw();

这样就只需要一个对象实现工厂

冷锋SJ记忆 冷锋SJ记忆

son***e_xuan@126.com

8年前 (2017-08-20)

#0 tongyu

tyy***28@sohu.com

101public class ShapeFactory {

public static T getClass(Class clazz) {

T obj = null;

try {

obj = (T) Class.forName(clazz.getName()).newInstance();

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (InstantiationException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

return obj;

}

}

省略类型强制转换,支持多态

Rectangle rect = ShapeFactory.getClass(Rectangle.class);

rect.draw();

Shape square = ShapeFactory.getClass(Square.class);

square.draw();tongyu tongyu

tyy***28@sohu.com

8年前 (2018-01-29)

#0 dugw

630***862@qq.com

36在上面的基础上进一步扩展,针对多个接口实现一个公共的工厂类:

public class ObjectFactory {

public Object getObject(Class clazz) {

if (clazz == null ) {

return null;

}

Object obj = null;

try {

obj = Class.forName(clazz.getName()).newInstance();

} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {

e.printStackTrace();

}

return obj;

}

}dugw dugw

630***862@qq.com

8年前 (2018-03-21)

#0 佐手

476***586@qq.com

32在jdk9中直接使用泛型的newInstance方法已经过时。重写的getClass()方法如下:

public T getClass(Class clazz) {

T obj = null;

try {

obj = clazz.getDeclaredConstructor().newInstance();

}

catch (ReflectiveOperationException e) {

e.printStackTrace();

}

return obj;

}佐手 佐手

476***586@qq.com

8年前 (2018-03-28)

#0 1310337382@qq.com

131***7382@qq.com

28public class ShapeFactory {

//使用 getShape 方法获取形状类型的对象

public Shape getShape(String shapeType){

if(shapeType == null){

return null;

}

if(shapeType.equalsIgnoreCase("CIRCLE")){

return new Circle();

} else if(shapeType.equalsIgnoreCase("RECTANGLE")){

return new Rectangle();

} else if(shapeType.equalsIgnoreCase("SQUARE")){

return new Square();

}

return null;

}

}

创建的这个工厂,这个创建函数,没能看出有什么特别的,还特别繁琐,如果IShape类太多,那么if else语句也将增加太多,不好维护,与其这样写,还不如改成如下:

public class ShapeFactory {

//使用 getShape 方法获取形状类型的对象

public Shape getShape(Class clazz){

try {

return (IShape) clazz.getConstructor().newInstance();

} catch (InstantiationException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (IllegalArgumentException e) {

e.printStackTrace();

} catch (InvocationTargetException e) {

e.printStackTrace();

} catch (NoSuchMethodException e) {

e.printStackTrace();

} catch (SecurityException e) {

e.printStackTrace();

}

return null;

}

}

这样写在创建时也不用知道具体的类别,易于管理维护。

1310337382@qq.com 1310337382@qq.com

131***7382@qq.com

8年前 (2018-04-03)

#0 kusirp21

hoo***@hotmail.com

787楼上几位真心会开玩笑!

其实使用反射是一种不错的办法,但反射也是从类名反射而不能从类反射!

先看一下工厂模式是用来干什么的——属于创建模式,解决子类创建问题的。换句话来说,调用者并不知道运行时真正的类名,只知道从“Circle"可以创建出一个shape接口的类,至于类的名称是否叫'Circle",调用者并不知情。所以真正的对工厂进行扩展的方式(防止程序员调用出错)可以考虑使用一个枚举类(防止传入参数时,把circle拼写错误)。

如果调用者参肯定类型是Circle的话,那么其工厂没有存在的意义了!

比如 IShape shape = new Circle();这样不是更好?也就是说调用者有了Circle这个知识是可以直接调用的,根据DP(迪米特法则)其实调用者并不知道有一个Circle类的存在,他只需要知道这个IShape接口可以计算圆面积,而不需要知道;圆这个类到底是什么类名——他只知道给定一个”circle"字符串的参数,IShape接口可以自动计算圆的面积就可以了!

其实在.net类库中存在这个模式的的一个典型的。但他引入的另一个概念“可插入编程协议”。

那个就是WebRequest req = WebRequest.Create("http://ccc......");可以自动创建一个HttpWebRequest的对象,当然,如果你给定的是一个ftp地址,他会自动创建一个FtpWebRequest对象。工厂模式中着重介绍的是这种通过某个特定的参数,让你一个接口去干对应不同的事而已!而不是调用者知道了类!

比如如果圆的那个类名叫"CircleShape“呢?不管是反射还是泛型都干扰了你们具体类的生成!其实这个要说明的问题就是这个,调用者(clinet)只知道IShape的存在,在创建时给IShape一个参数"Circle",它可以计算圆的面积之类的工作,但是为什么会执行这些工作,根据迪米特法则,client是不用知道的。

我想问一下那些写笔记的哥们,如果你们知道了泛型,那么为什么不直接使用呢?干吗还需要经过工厂这个类呢?不觉得多余了吗?

如果,我只是说如果,如果所有从IShape继承的类都是Internal类型的呢?而client肯定不会与IShape一个空间!这时,你会了现你根本无法拿到这个类名!

Create时使用注册机制是一种简单的办法,比如使用一个枚举类,把功能总结到一处。而反射也是一种最简单的办法,调用者输入的名称恰是类名称或某种规则时使用,比如调用者输入的是Circle,而类恰是CircleShape,那么可以通过输入+”Shape"字符串形成新的类名,然后从字符串将运行类反射出来!

工厂的创建行为,就这些作用,还被你们用反射或泛型转嫁给了调用者(clinet),那么,这种情况下,要工厂类何用?!

kusirp21 kusirp21

hoo***@hotmail.com

7年前 (2018-06-17)

#0 罗

107***8153@qq.com

参考地址

32使用枚举优化

public enum Factory {

CIRCLE(new Circle(),"CIRCLE"),

RECTANGLE(new Rectangle(),"RECTANGLE"),

SQUARE(new Square(),"SQUARE");

// 成员变量

private Shape shape;

private String name;

// 普通方法

public static Shape getShape(String name) {

for (Factory c : Factory.values()) {

if (c.name == name) {

return c.shape;

}

}

return null;

}

// 构造方法

private Factory(Shape shape, String name) {

this.shape = shape;

this.name = name;

}

public String getName() {

return name;

}

public Shape getShape() {

return shape;

}

public void setShape(Shape shape) {

this.shape = shape;

}

public void setName(String name) {

this.name = name;

}

}

/*使用枚举类*/

Factory.getShape("CIRCLE").draw();

Factory.getShape("RECTANGLE").draw();

Factory.getShape("SQUARE").draw();罗 罗

107***8153@qq.com

参考地址

7年前 (2018-07-02)

#0 往生在世

493***942@qq.com

25使用类名增加耦合性,那就需要使用常量或者枚举类解耦合。

// 接口 增加常量或枚举

public interface Shape {

static String SHAPE_YUAN = Yuan.class.getName();

static String SHAPE_FANG = Fang.class.getName();

static String SHAPE_CHANG = Chang.class.getName();

void draw();

}

// 工厂方法

public class Factory {

public static Shape getShape2(String type) {

try {

return (Shape) Class.forName(type).getDeclaredConstructor().newInstance();

} catch (InstantiationException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (IllegalArgumentException e) {

e.printStackTrace();

} catch (InvocationTargetException e) {

e.printStackTrace();

} catch (NoSuchMethodException e) {

e.printStackTrace();

} catch (SecurityException e) {

e.printStackTrace();

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

return null;

}

}

// 调用

Shape s21 = Factory.getShape2(Shape.SHAPE_CHANG);

s21.draw();

Shape s22 = Factory.getShape2(Shape.SHAPE_FANG);

s22.draw();

Shape s23 = Factory.getShape2(Shape.SHAPE_YUAN);

s23.draw();往生在世 往生在世

493***942@qq.com

7年前 (2018-07-09)

#0 牟春平

muc***ping@gmail.com

28@kusirp21 讲得很好,使用枚举类优化。

增加枚举类

public enum ShapeType{

CIRCLE,

RECTANGLE,

SQUARE

}

修改工厂类的工厂方法,个人建议工厂方法应该是静态方法或者采用单例模式:

public class ShapeFactory{

public static Shape getShape(ShapeType type){

switch(type){

case CIRCLE:

return new Circle();

case RECTANGLE:

return new Rectangle();

case SQUARE:

return new Square();

default:

throw new UnknownTypeException();

}

}

}

上面用到的类和接口与课程中的一样。

最后是使用示例:

public class FactoryPatternDemo {

public static void main(String[] args) {

//获取 Circle 的对象,并调用它的 draw 方法

Shape shape1 = ShapeFactory.getShape(ShapeType.CIRCLE);

//调用 Circle 的 draw 方法

shape1.draw();

//获取 Rectangle 的对象,并调用它的 draw 方法

Shape shape2 = ShapeFactory.getShape(ShapeType.RECTANGLE);

//调用 Rectangle 的 draw 方法

shape2.draw();

//获取 Square 的对象,并调用它的 draw 方法

Shape shape3 = ShapeFactory.getShape(ShapeType.SQUARE);

//调用 Square 的 draw 方法

shape3.draw();

}

}

牟春平 牟春平

muc***ping@gmail.com

7年前 (2018-07-26)

#0 msyms

934***531@qq.com

参考地址

103一、一句话概括工厂模式

简单工厂:一个工厂类,一个产品抽象类。

工厂方法:多个工厂类,一个产品抽象类。

抽象工厂:多个工厂类,多个产品抽象类。

二、生活中的工厂模式

简单工厂类:一个麦当劳店,可以生产多种汉堡。

工厂方法类:一个麦当劳店,可以生产多种汉堡。一个肯德基店,也可以生产多种汉堡。

抽象工厂类:百胜餐饮集团下有肯德基和百事公司,肯德基生产汉堡,百事公司生成百事可乐。

msyms msyms

934***531@qq.com

参考地址

7年前 (2018-10-20)

#0 李金晨

231***8763@qq.com

18工厂模式实例:

package 工厂设计模式;

public class Factory_pattern {

public static void main(String[] args) {

Factory facortoy = new Factory();

Person zgr = facortoy.getInstance("zgr");

zgr.eat();

}

}

//人类都具有吃方法

interface Person{

public void eat();

}

//中国人

class zgr implements Person{

@Override

public void eat() {

System.out.println("中国人吃饭用筷子");

}

}

//印度人

class ydr implements Person{

@Override

public void eat() {

System.out.println("印度人用手吃饭");

}

}

//美国人

class mgr implements Person{

@Override

public void eat() {

System.out.println("美国人用刀和叉子吃饭");

}

}

interface Instance{

public Person getInstance(String str);

}

class Factory implements Instance{

@Override

public Person getInstance(String str) {

if(str.equals("zgr")) {

return new zgr();

}else if(str.equals("ydr")) {

return new ydr();

}else if(str.equals("mgr")) {

return new mgr();

}else {

return null;

}

}

}

李金晨 李金晨

231***8763@qq.com

7年前 (2018-10-21)

#0 Robbie

g00***00@126.com

10根据上面 @kusirp21 枚举的思路实现的工厂模式:

public enum ShapeType {

CIRCLE(new Circle()), RECTANGLE(new Rectangle()), SQUARE(new Square());

private Shape shape;

private ShapeType(Shape shape) {

this.shape = shape;

}

public Shape getShape() {

return shape;

}

}

public class Test {

public static void main(String[] args) {

ShapeType.CIRCLE.getShape().draw();

}

}Robbie Robbie

g00***00@126.com

7年前 (2018-11-14)

#0 阿燃

357***211@qq.com

7接口定义实现类的规范,通过反射工厂类进行生产,完整的一个过程就是。

接口类:

public interface Shape {

void draw();

}

实现类:

public class Rectangle implements Shape{

@Override public void draw() {

System.out.println("Rectangle");

}

}

public class Square implements Shape{

@Override public void draw() {

System.out.println("Square");

}

}

工厂类:

public class ShapeFactory{

public static Shape getClass(Class clazz) {

Shape o = null;

try {

o = (Shape) Class.forName(clazz.getName()).newInstance();

} catch (InstantiationException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

return o;

}

}

}

给定条件产出:

public class FactoryModeImpl {

public static void main(String[] args) {

Shape shape = ShapeFactory.getClass(Square.class);

shape.draw();

}

}阿燃 阿燃

357***211@qq.com

7年前 (2018-12-22)

#0 杨轻帆

294***4412@qq.com

5在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

此练习中我写的工厂是通过一个方法(买狗)来调用相应对象创建语句去创建不同的(狗)对象;用子对象中的重写方法验证父对象被赋值后调用的方法是属于谁的。

具体的解释在代码中已经标明:

import java.util.Scanner;

//多态

public class Test2 {

public static void main(String[] args) {

Factory no1=new Factory();//创建工厂对象

no1.maigou();//调用工厂的方法(买狗)

}

}

class Factory{

public void maigou(){

Dog1 dog=new Dog1();

System.out.println("要买什么狗?");

Scanner sc=new Scanner(System.in);

String str=sc.nextLine();

switch(str){

default:

System.out.println("没有这玩意儿");

break;

case "金毛" :

dog=new Jinmao();

dog.show();

break;//将子类赋值给父类并调用重写后的方法

case "二哈" :

dog=new Erha();

dog.show();//将子类赋值给父类并调用重写后的方法

}

}

}

class Dog1{ //这里因为Dog类在其他包里建过了,为了避免冲突,取名Dog1

public void show(){

System.out.println("这是一只狗");

}

}

class Erha extends Dog1{

public void show(){

System.out.println("这是一只二哈");//通过重写函数show验证dog对象调用的方法是谁的

}

}

class Jinmao extends Dog1{

public void show(){

System.out.println("这是一只金毛");//通过重写函数show验证dog对象调用的方法是谁的

}

}

杨轻帆 杨轻帆

294***4412@qq.com

6年前 (2019-08-08)

#0 BertYY

zge***an@hotmail.com

7python 代码实现示例:

class Shape(object):

def draw(self):

pass

class RectangleImplementsShape(Shape):

def __init__(self):

print("this relalize Interface")

def draw(self):

print("Inside Rectangle::draw() method.")

class SquareImplementsShape(Shape):

def __init__(self):

print("this relalize Interface")

def draw(self):

print("Inside Square::draw() method.")

class CircleImplementsShape(Shape):

def __init__(self):

print("this relalize Interface")

def draw(self):

print("Inside Circle::draw() method.")

class ShapeFactory(object):

def __init__(self):

print("ShapeFactory init")

def getShape(self,method):

if method.lower() == 'rectangle':

return RectangleImplementsShape()

if method.lower() == 'square':

return SquareImplementsShape()

if method.lower() == 'circle':

return CircleImplementsShape()

shapeFactory = ShapeFactory()

shap1 = shapeFactory.getShape('Rectangle')

shap2 = shapeFactory.getShape('Square')

shap3 = shapeFactory.getShape('Circle')

shap1.draw()

shap2.draw()

shap3.draw()BertYY BertYY

zge***an@hotmail.com

6年前 (2019-08-24)

#0 Siskin.xu

sis***@sohu.com

6Python 方式:

# Python原生默认不支持接口,默认多继承,所有的方法都必须不能实现

from abc import abstractmethod,ABCMeta

# 声明一个抽象接口

class Shape(metaclass=ABCMeta):

@abstractmethod

def draw(self):

pass

# 三个形状继承实现 Shape 接口

class Rectangle(Shape):

def draw(self):

print("Inside Ractangle.draw method")

class Square(Shape):

def draw(self):

print("Inside Square.draw method")

class Circle(Shape):

def draw(self):

print("Inside Circle.draw method")

# 创建一个工厂

class ShapeFactory():

def getShape(self,shapeType):

if shapeType == None :

return None

elif shapeType.upper() == "CIRCLE":

return Circle()

elif shapeType.upper() == "RECTANGLE":

return Rectangle()

elif shapeType.upper() == "SQUARE":

return Square()

return None

# 输出

if __name__ == '__main__':

shapeFactory = ShapeFactory()

shape1 = shapeFactory.getShape("CIRCLE")

shape1.draw()

shape2 = shapeFactory.getShape("RECTANGLE")

shape2.draw()

shape3 = shapeFactory.getShape("SQUARE")

shape3.draw()Siskin.xu Siskin.xu

sis***@sohu.com

6年前 (2020-02-28)

#0 清露凝尘

575***823@qq.com

22看了大家的笔记,差点误入歧途,感谢 @kusirp21 的当头棒喝。取长补短,将工厂方法中的判断,提取到枚举中, 工厂方法使用反射创建对象。

以下是代码:

public interface Shape { void draw();}

public class Circle implements Shape {

@Override public void draw() {

System.out.println("圆形");

}

}

public class Rectangle implements Shape {

@Override public void draw() {

System.out.println("矩形");

}

}

public class Square implements Shape {

@Override public void draw() {

System.out.println("正方形");

}

}

public enum ShapeTypeEnum {

CIRCLE("com.example.factorymethods.Circle"),

SQUARE("com.example.factorymethods.Square"),

RECTANGLE("com.example.factorymethods.Rectangle");

private String className;

ShapeTypeEnum(String className) {

this.className = className;

}

public String getClassName() {

return className;

}

}

public class ShapeFactory {

private ShapeFactory(){}

/**

*

* 创建不同的图形实例

* @param shapeTypeEnum

* @return

*/

public static Shape createShape(ShapeTypeEnum shapeTypeEnum){

Shape shape = null;

String className = shapeTypeEnum.getClassName();

try {

Class clazz = Class.forName(className);

shape = (Shape)clazz.newInstance();

} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {

e.printStackTrace();

}

return shape;

}

}

public class FactoryMethodsDemo {

public static void main(String[] args) {

ShapeFactory.createShape(ShapeTypeEnum.CIRCLE).draw();

ShapeFactory.createShape(ShapeTypeEnum.SQUARE).draw();

ShapeFactory.createShape(ShapeTypeEnum.RECTANGLE).draw();

}

}

清露凝尘 清露凝尘

575***823@qq.com

5年前 (2020-05-13)

#0 不在窝里

yzq***p@163.com

5清露凝尘的做法非常好,我借鉴之后,减少了一下代码量,个人觉得效果达到,编码也少,这样挺好。

以下修改了异常抛出结果,简单做了下拼接。

public interface shape {

//绘画接口

void draw();

}

public class Rectangle implements shape{

@Override

public void draw() {

// TODO Auto-generated method stub

System.out.println("restangle中的绘画");

}

}

public class Square implements shape{

@Override

public void draw() {

// TODO Auto-generated method stub

System.out.println("Square中的绘画");

}

}

package com.yzq.pattren.createPattern.factoryPattern;

public class ShapeFactory {

//优化getShape

public shape getPlusShape(String shapeType) {

// TODO Auto-generated method stub

try {

//forName返回与给定的字符串名称相关联类或接口的Class对象

Class clazz = Class.forName(shapeType);

return (com.yzq.pattren.createPattern.factoryPattern.shape) clazz.newInstance();

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return null;

}

}

测试类:

public class TestCreatePattern {

public static void main(String[] args) {

//工厂模式

ShapeFactory shapeFactory = new ShapeFactory();

//配置一个BaseFactory,指定范围查找类名。

String BaseFactory = "com.yzq.pattren.createPattern.factoryPattern.";

//Square,Rectangle代表用户提交的选择框的信息

shapeFactory.getPlusShape(BaseFactory+"Square").draw();

shapeFactory.getPlusShape(BaseFactory+"Rectangle").draw();

}

}不在窝里 不在窝里

yzq***p@163.com

5年前 (2020-07-20)

#0 蘑菇力

168***7348@qq.com

5反射很方便。

//示例:

//创建一个Car服务接口

interface CarService{

//比如为Car创建一个run()方法

void run();

}

//创建一个工厂类

public class CarFactory{

public static void main(String []args){

try{

//创建Properties对象

Properties properties = new Properties();

//类加载器读取配置文件

InputStream is = CarFactory.class.getClassLoader().getResourceAsStream("car.properties");

properties.load(is);

is.close();

//通过Entry遍历<迭代Entry>

for (Entry entry : properties.entrySet()) {

//动态创建实现类对象,只要在配置文件中的类,都会创建并运行

CarService cs = (CarService) Class.forName((String) entry.getValue()).newInstance();

//接口回调

cs.run();

}

}catch(Exception e){

e.printStackTrace();

}

}

}

//创建类实现CarService接口

class BMW implements CarService{

String name = "BMW";

public void run(){

System.out.println(name+"正在路上飞驰。。。");

}

}

public class Benz implements CarService {

String name = "Benz";

public void run(){

System.out.println(name+"正在路上飞驰。。。");

}

}

//创建car.properties文件,将实现类的全限定名放在配置文件中

BMW=com.runoob.car.BMW

Bean=com.runoob.Benz

以上这种方法,便于维护,创建对象时,只需要该类实现Service接口,并在配置文件中添加该类的全限定名即可。类似于插件开发。

蘑菇力 蘑菇力

168***7348@qq.com

5年前 (2020-12-26)

#0 fanjinzhao

165***6686@qq.com

11在逻辑代码中应避免出现"魔法值"。

结合之前几位的逻辑,我将反射和枚举类结合一起并完善,写出下面代码:

public class SimpleFactory {

public static void main(String[] args) {

Animal dog = factory("Dog");

assert dog != null;

dog.run();

Animal cat = factory("Cat");

assert cat != null;

cat.run();

}

public static Animal factory(String simpleName){

//获取枚举类中对应的全类名

simpleName = AnimalEnum.getName(simpleName);

if(simpleName == null || simpleName.length() <= 0){

return null;

}

try {

return (Animal) Class.forName(simpleName).getConstructor().newInstance();

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

}

//动物接口

interface Animal{

void run();

}

//狗实现类

class Dog implements Animal{

public Dog() {}

@Override

public void run() {

System.out.println("小狗跑");

}

}

//猫实现类

class Cat implements Animal{

public Cat() {}

@Override

public void run() {

System.out.println("小猫跑");

}

}

//动物枚举

enum AnimalEnum{

DOG("Dog",Dog.class.getName()),

CAT("Cat",Cat.class.getName());

private final String simpleName;

private final String name;

AnimalEnum(String simpleName, String name) {

this.simpleName = simpleName;

this.name = name;

}

public String getSimpleName() {

return simpleName;

}

public String getName() {

return name; }

//获通过动物简易名获取动物全类名

public static String getName(String simpleName){

for( AnimalEnum animalEnum : AnimalEnum.values()){

if(animalEnum.getSimpleName().equalsIgnoreCase(simpleName)){

return animalEnum.getName();

}

}

return null;

}

}fanjinzhao fanjinzhao

165***6686@qq.com

5年前 (2021-02-22)

#0 mm

mfx***0@live.cn

4C++ 的实现方法:

#include

using std::string;

using std::cout;

using std::endl;

class Shape{

public:

virtual void draw() {

cout<<"this is virtual fun,cannot do something."<

};

static Shape* getShape(string shapeType);

};

class Rectangle : public Shape{

public:

void draw(){

cout<<"Inside Rectangle::draw() method."<

}

};

class Square : public Shape{

public:

void draw(){

cout<<"Inside Square::draw() method."<

}

};

class Circle : public Shape{

public:

void draw(){

cout<<"Inside Circle::draw() method."<

}

};

Shape* Shape::getShape(string shapeType){

if(shapeType == "CIRCLE"){

return new Circle();

} else if(shapeType == "RECTANGLE"){

return new Rectangle();

} else if(shapeType == "SQUARE" ){

return new Square();

}

return new Shape();

}

int main(){

Shape* shape1=NULL;

shape1 = Shape::getShape("CIRCLE");

shape1->draw();

shape1 = Shape::getShape("RECTANGLE");

shape1->draw();

shape1 = Shape::getShape("SQUARE");

shape1->draw();

return 0;

}mm mm

mfx***0@live.cn

5年前 (2021-04-03)

#0 squid233

513***220@qq.com

2改良版 C++ 方式:

#include

#include

using namespace std;

class Shape {

public:

virtual void draw() = 0;

};

class Rectangle : public Shape {

public:

void draw() {

cout << "Inside Rectangle::draw() method." << endl;

}

};

class Square : public Shape {

public:

void draw() {

cout << "Inside Square::draw() method." << endl;

}

};

class Circle : public Shape {

public:

void draw() {

cout << "Inside Circle::draw() method." << endl;

}

};

class ShapeFactory {

public:

void getShape(string shapeType, Shape** shape) {

string type = shapeType;

#ifdef __GNUC__

transform(type.begin(), type.end(), type.begin(), ::toupper);

#else

transform(type.begin(), type.end(), type.begin(), toupper);

#endif

if (type == "CIRCLE") {

*shape = new Circle();

} else if (type == "RECTANGLE") {

*shape = new Rectangle();

} else if (type == "SQUARE") {

*shape = new Square();

}

}

};

int main() {

ShapeFactory shapeFactory;

//获取 Circle 的对象,并调用它的 draw 方法

Shape* shape1;

shapeFactory.getShape("CIRCLE", &shape1);

//调用 Circle 的 draw 方法

shape1->draw();

delete shape1;

//获取 Rectangle 的对象,并调用它的 draw 方法

Shape* shape2;

shapeFactory.getShape("RECTANGLE", &shape2);

//调用 Rectangle 的 draw 方法

shape2->draw();

delete shape2;

//获取 Square 的对象,并调用它的 draw 方法

Shape* shape3;

shapeFactory.getShape("SQUARE", &shape3);

//调用 Square 的 draw 方法

shape3->draw();

delete shape3;

}squid233 squid233

513***220@qq.com

4年前 (2021-06-05)

#0 MJ123

MJ1***6019027@126.com

5C# 入门版:

namespace FactoryPattern

{

///

/// 方式1:接口作为父类

///

public interface ISayHello

{

void SayHello();

}

///

/// 汉语

///

public class Chinese : ISayHello

{

private string _name;

public Chinese()

{

}

public Chinese(string name)

{

_name = name;

}

public void SayHello()

{

Console.WriteLine("大家好,我是 " + _name);

}

}

///

/// 英语

///

public class American : ISayHello

{

private string _name;

public American()

{

}

public American(string name)

{

_name = name;

}

public void SayHello()

{

Console.WriteLine("Hello Everyone, I'm " + this._name);

}

}

///

/// 日语

///

public class Japanese : ISayHello

{

public void SayHello()

{

Console.WriteLine("こんにちは、我是小日子过的不错的日本人");

}

}

public enum LanguageType

{

Chinese,

English,

Janpanese

}

///

/// 工厂类

///

public class LanguageFactory

{

public static ISayHello GetLanguage(LanguageType type)

{

switch (type)

{

case LanguageType.Chinese:

return new Chinese("小明");

case LanguageType.English:

return new American("MJ");

case LanguageType.Janpanese:

return new Japanese();

default:

return null;

}

}

}

///

///

///

internal class Program

{

static void Main(string[] args)

{

LanguageFactory.GetLanguage(LanguageType.Chinese).SayHello();

LanguageFactory.GetLanguage(LanguageType.English).SayHello();

LanguageFactory.GetLanguage(LanguageType.Janpanese).SayHello();

Console.ReadKey();

}

}

}

MJ123 MJ123

MJ1***6019027@126.com

3年前 (2022-12-05)

#0 RUNOOB

429***967@qq.com

5

工厂模式可以帮助我们封装对象的创建逻辑,提供统一的接口来创建不同类型的对象,从而使得客户端代码更加灵活和可维护。同时,工厂模式也支持扩展,可以方便地引入新的产品类型,而无需修改现有的客户端代码。

工厂模式有多种变体,其中最常见的是简单工厂模式、工厂方法模式和抽象工厂模式。

简单工厂模式(Simple Factory Pattern):由一个具体工厂类负责创建所有产品的实例。客户端通过向工厂传递不同的参数来请求创建不同类型的产品。简单工厂模式通常只有一个具体工厂类,适用于创建对象较少且创建逻辑相对简单的情况。工厂方法模式(Factory Method Pattern):定义了一个创建产品的抽象方法,由具体子类工厂来实现创建具体产品的过程。每个具体工厂类负责创建一种具体产品。工厂方法模式可以实现客户端与具体产品的解耦,允许系统在不修改客户端代码的情况下引入新产品。抽象工厂模式(Abstract Factory Pattern):提供了一组相关或相互依赖的产品对象的创建接口。每个具体工厂类负责创建一组具体产品。抽象工厂模式可以用于创建一族产品,而不仅仅是单个产品。

下面是一个简单工厂模式的示例:

// 抽象产品

interface Product {

void operation();

}

// 具体产品

class ConcreteProductA implements Product {

public void operation() {

System.out.println("ConcreteProductA operation");

}

}

class ConcreteProductB implements Product {

public void operation() {

System.out.println("ConcreteProductB operation");

}

}

// 简单工厂

class SimpleFactory {

public Product createProduct(String type) {

if (type.equals("A")) {

return new ConcreteProductA();

} else if (type.equals("B")) {

return new ConcreteProductB();

}

return null;

}

}

// 使用示例

public class Main {

public static void main(String[] args) {

SimpleFactory factory = new SimpleFactory();

Product productA = factory.createProduct("A");

productA.operation(); // Output: ConcreteProductA operation

Product productB = factory.createProduct("B");

productB.operation(); // Output: ConcreteProductB operation

}

}

在上面的示例中,我们定义了抽象产品接口 Product 和具体产品类 ConcreteProductA 和 ConcreteProductB。通过简单工厂类 SimpleFactory 的 createProduct 方法,根据传入的参数类型来创建不同的具体产品实例。

RUNOOB RUNOOB

429***967@qq.com

2年前 (2023-07-11)

相关推荐

驾驶证c升b需要多少钱
足球365网站网址

驾驶证c升b需要多少钱

📅 07-10 👁️ 9226
大话西游手游男鬼带什么宠物  男鬼宠物推荐
足球365网站网址

大话西游手游男鬼带什么宠物 男鬼宠物推荐

📅 07-18 👁️ 4037
明线怎么遮丑0
足球365网站网址

明线怎么遮丑0

📅 07-19 👁️ 9133