CSharp: Factory Method Pattern in donet core 3

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#region Animal Hierarchy
/*
 * Both the Dog and Tiger classes will
 * implement the IAnimal interface method.
*/
/// <summary>
/// 工厂方法模式 Factory Method Pattern
/// geovindu,Geovin Du  eidt
/// </summary>
public interface IAnimal
{
    void AboutMe();
}
/// <summary>
/// Dog class
/// </summary>
public class Dog : IAnimal
{
    public void AboutMe()
    {
        Console.WriteLine("The dog says: Bow-Wow.I prefer barking.");
    }
}
/// <summary>
/// Tiger class
/// </summary>
public class Tiger : IAnimal
{
    public void AboutMe()
    {
        Console.WriteLine("The tiger says: Halum.I prefer hunting.");
    }
}
#endregion
 
#region Factory Hierarchy
 
/// <summary>
/// Both DogFactory and TigerFactory will use this.
/// </summary>
public abstract class AnimalFactory
{
    /*
    Remember the GoF definition which says
    "....Factory method lets a class defer instantiation
    to subclasses." Following method will create a Tiger
    or a Dog, but at this point it does not know whether
    it will get a dog or a tiger. It will be decided by
    the subclasses i.e.DogFactory or TigerFactory.
    So, the following method is acting like a factory
    (of creation).
    */
    public abstract IAnimal CreateAnimal(string animalType);
}
/*
 * ConcreteAnimalFactory is used to create dogs or tigers
 * based on method parameter of CreateAnimal() method.
 */
/// <summary>
///
/// </summary>
public class ConcreteAnimalFactory : AnimalFactory
{
 
    /// <summary>
    ///
    /// </summary>
    /// <param name="animalType"></param>
    /// <returns></returns>
    /// <exception cref="ArgumentException"></exception>
    public override IAnimal CreateAnimal(string animalType)
    {
        if (animalType.Contains("dog"))
        {
            //Creating a Dog
            return new Dog();
        }
        else
        if (animalType.Contains("tiger"))
        {
            //Creating a Dog
            return new Tiger();
        }
        else
        {
            throw new ArgumentException("You need to pass either a dog or a tiger as an argument.");
        }
    }
}
 
#endregion

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/// <summary>
/// 工厂方法模式 Factory Method Pattern
/// geovindu,Geovin Du  eidt
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IAsyncInit<T>
{
    Task<T> InitAsync();
}
/// <summary>
///
/// </summary>
public class Foo : IAsyncInit<Foo>
{
    /*public*/
    public Foo()
    {
        // await Task.Delay(1000);
     
    }
 
    // ↓↓
    public async Task<Foo> InitAsync()
    {
        // some work here
        Console.WriteLine("some work here");
        await Task.Delay(1000);
        return this; // fluent
    }
 
    public static Task<Foo> CreateAsync()
    {
        var result = new Foo();
        return result.InitAsync();
    }
}
/// <summary>
///
/// </summary>
public static class AsyncFactory
{
    public static async Task<T> Create<T>()
      where T : IAsyncInit<T>, new()
    {
        var result = await new T().InitAsync();
        return result;
    }
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/// <summary>
   /// 抽象工厂模式 Abstract Factory Pattern
   /// geovindu,Geovin Du  eidt
   /// </summary>
   public interface IShape
   {
       void Draw();
   }
   /// <summary>
   ///
   /// </summary>
   public class Square : IShape
   {
       public void Draw() => Console.WriteLine("Basic square");
   }
   /// <summary>
   ///
   /// </summary>
   public class Rectangle : IShape
   {
       public void Draw() => Console.WriteLine("Basic rectangle");
   }
   /// <summary>
   ///
   /// </summary>
   public class RoundedSquare : IShape
   {
       public void Draw() => Console.WriteLine("Rounded square");
   }
   /// <summary>
   ///
   /// </summary>
   public class RoundedRectangle : IShape
   {
       public void Draw() => Console.WriteLine("Rounded rectangle");
   }
   /// <summary>
   ///
   /// </summary>
   public enum Shape
   {
       Square,
       Rectangle
   }
   /// <summary>
   ///
   /// </summary>
   public abstract class ShapeFactory
   {
       public abstract IShape Create(Shape shape);
   }
   /// <summary>
   ///
   /// </summary>
   public class BasicShapeFactory : ShapeFactory
   {
       public override IShape Create(Shape shape)
       {
           switch (shape)
           {
               case Shape.Square:
                   return new Square();
               case Shape.Rectangle:
                   return new Rectangle();
               default:
                   throw new ArgumentOutOfRangeException(
                     nameof(shape), shape, null);
           }
       }
   }
   /// <summary>
   ///
   /// </summary>
   public class RoundedShapeFactory : ShapeFactory
   {
       public override IShape Create(Shape shape)
       {
           switch (shape)
           {
               case Shape.Square:
                   return new RoundedSquare();
               case Shape.Rectangle:
                   return new RoundedRectangle();
               default:
                   throw new ArgumentOutOfRangeException(nameof(shape), shape, null);
           }
       }
   }
   /// <summary>
   ///
   /// </summary>
   public class Demo
   {
       public static ShapeFactory GetFactory(bool rounded)
       {
           if (rounded)
               return new RoundedShapeFactory();
           else
               return new BasicShapeFactory();
       }
   }

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/// <summary>
/// 工厂方法模式 Factory Method Pattern
/// geovindu,Geovin Du  eidt
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IAsyncInit<T>
{
    Task<T> InitAsync();
}
/// <summary>
///
/// </summary>
public class Foo : IAsyncInit<Foo>
{
    /*public*/
    public Foo()
    {
        // await Task.Delay(1000);
     
    }
 
    // ↓↓
    public async Task<Foo> InitAsync()
    {
        // some work here
        Console.WriteLine("some work here");
        await Task.Delay(1000);
        return this; // fluent
    }
 
    public static Task<Foo> CreateAsync()
    {
        var result = new Foo();
        return result.InitAsync();
    }
}
/// <summary>
///
/// </summary>
public static class AsyncFactory
{
    public static async Task<T> Create<T>()
      where T : IAsyncInit<T>, new()
    {
        var result = await new T().InitAsync();
        return result;
    }
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/// <summary>
   /// 工厂方法模式 Factory Method Pattern
   /// geovindu,Geovin Du  eidt
   /// </summary>
   public interface IHotDrink
   {
       void Consume();
   }
   /// <summary>
   ///
   /// </summary>
   internal class Tea : IHotDrink
   {
       public void Consume()
       {
           Console.WriteLine("This tea is nice but I'd prefer it with milk.");
       }
   }
   /// <summary>
   ///
   /// </summary>
   internal class Coffee : IHotDrink
   {
       public void Consume()
       {
           Console.WriteLine("This coffee is delicious!");
       }
   }
   /// <summary>
   ///
   /// </summary>
   public interface IHotDrinkFactory
   {
       IHotDrink Prepare(int amount);
   }
   /// <summary>
   ///
   /// </summary>
   internal class TeaFactory : IHotDrinkFactory
   {
       public IHotDrink Prepare(int amount)
       {
           Console.WriteLine($"Put in tea bag, boil water, pour {amount} ml, add lemon, enjoy!");
           return new Tea();
       }
   }
   /// <summary>
   ///
   /// </summary>
   internal class CoffeeFactory : IHotDrinkFactory
   {
       public IHotDrink Prepare(int amount)
       {
           Console.WriteLine($"Grind some beans, boil water, pour {amount} ml, add cream and sugar, enjoy!");
           return new Coffee();
       }
   }
   /// <summary>
   ///
   /// </summary>
   public class HotDrinkMachine
   {
 
       /// <summary>
       ///
       /// </summary>
       public enum AvailableDrink // violates open-closed
       {
           Coffee, Tea
       }
 
       private Dictionary<AvailableDrink, IHotDrinkFactory> factories =
         new Dictionary<AvailableDrink, IHotDrinkFactory>();
 
       private List<Tuple<string, IHotDrinkFactory>> namedFactories =
         new List<Tuple<string, IHotDrinkFactory>>();
       /// <summary>
       ///
       /// </summary>
       public HotDrinkMachine()
       {
           //foreach (AvailableDrink drink in Enum.GetValues(typeof(AvailableDrink)))
           //{
           //  var factory = (IHotDrinkFactory) Activator.CreateInstance(
           //    Type.GetType("DotNetDesignPatternDemos.Creational.AbstractFactory." + Enum.GetName(typeof(AvailableDrink), drink) + "Factory"));
           //  factories.Add(drink, factory);
           //}
 
           foreach (var t in typeof(HotDrinkMachine).Assembly.GetTypes())
           {
               if (typeof(IHotDrinkFactory).IsAssignableFrom(t) && !t.IsInterface)
               {
                   namedFactories.Add(Tuple.Create(
                     t.Name.Replace("Factory", string.Empty), (IHotDrinkFactory)Activator.CreateInstance(t)));
               }
           }
       }
       /// <summary>
       ///
       /// </summary>
       /// <param name="type"></param>
       /// <returns></returns>
       /// <exception cref="ArgumentException"></exception>
       public IHotDrink MakeDrink(string type)
       {
           switch (type)
           {
               case "tea":
                   return new TeaFactory().Prepare(200);
               case "coffee":
                   return new CoffeeFactory().Prepare(50);
               default:
                   throw new ArgumentException("type");
           }
       }
       /// <summary>
       ///
       /// </summary>
       /// <returns></returns>
       public IHotDrink MakeDrink()
       {
           Console.WriteLine("Available drinks");
           for (var index = 0; index < namedFactories.Count; index++)
           {
               var tuple = namedFactories[index];
               Console.WriteLine($"{index}: {tuple.Item1}");
 
           }
 
           while (true)
           {
               string s;
               if ((s = Console.ReadLine()) != null
                   && int.TryParse(s, out int i) // c# 7
                   && i >= 0
                   && i < namedFactories.Count)
               {
                   Console.Write("Specify amount: ");
                   s = Console.ReadLine();
                   if (s != null
                       && int.TryParse(s, out int amount)
                       && amount > 0)
                   {
                       return namedFactories[i].Item2.Prepare(amount);
                   }
               }
               Console.WriteLine("Incorrect input, try again.");
           }
       }
 
       //public IHotDrink MakeDrink(AvailableDrink drink, int amount)
       //{
       //  return factories[drink].Prepare(amount);
       //}
   }

  

调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//
            Console.WriteLine("***工厂方法模式 Factory Pattern Demo.***");
            Console.WriteLine("***It's a modified version using method parameter(s).***\n");
            // Creating a factory that can produce animals
            AnimalFactory animalFactory = new ConcreteAnimalFactory();
            // Creating a tiger using the Factory Method
            IAnimal tiger = animalFactory.CreateAnimal("tiger");
            tiger.AboutMe();
            //Now creating a dog.         
            IAnimal dog = animalFactory.CreateAnimal("dog");
            dog.AboutMe();
 
            //抽象工厂模式
            var basic = Demo.GetFactory(false);
            var basicRectangle = basic.Create(Shape.Rectangle);
            basicRectangle.Draw();
 
            var roundedSquare = Demo.GetFactory(true).Create(Shape.Square);
            roundedSquare.Draw();
 
 
            // instead
             var foo = Foo.CreateAsync();// Foo.CreateAsync();
            // or
             var foo2 = AsyncFactory.Create<Foo>();
            //
            var machine = new HotDrinkMachine();
            //var drink = machine.MakeDrink(HotDrinkMachine.AvailableDrink.Tea, 300);
            //drink.Consume();
 
            IHotDrink drink = machine.MakeDrink();
            drink.Consume();
 
            Console.ReadKey();

  

输出:

1
2
3
4
5
6
7
8
9
10
11
12
***工厂方法模式 Factory Pattern Demo.***
***It's a modified version using method parameter(s).***
 
The tiger says: Halum.I prefer hunting.
The dog says: Bow-Wow.I prefer barking.
Basic rectangle
Rounded square
some work here
some work here
Available drinks
0: Tea
1: Coffee

  

posted @   ®Geovin Du Dream Park™  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示