Detailed application of Singleton, Factory, Strategy in project

1. Preface

The other day I read a framework document with a description like "From an object factory......"Prompted to write this article.Although some patterns are simple and simple, they are common and useful.

In conjunction with a recent project scenario, review some of the patterns applied to Singleton, Factory, Strategy.

  • Singleton: Creative mode responsible for creating and maintaining a globally unique instance
  • Factory: Create pattern, the object factory is responsible for creating or getting specific instance objects based on identity
  • Strategy: Behavioral/Runtime mode, which controls the behavior of the application at runtime based on identity

2. Scene context

Project Requirements/Scenarios: Automated testing of specific applications using scripting programs with additional assistive tools, including clicking buttons, selecting menus, reading control content, etc.

Original implementation: The script <AutoIt>performs an "automated test" of a specific application by calculating coordinates.Disadvantages: large workload of scripting, relying on button screen coordinates, complex coordinate calculation, relying on screen resolution, etc.

Target program simplification diagram:

Before using assistive tools:

After using assistive tools:

3. Analysis and Design

Only the auxiliary tools are analyzed and designed here, others are skipped.

1. Fig. 1 The target program has the following main features:

  • The target program is divided into five functional areas A-E
  • Each ribbon has similar functions as buttons, menus, etc.
  • Each ribbon has its own features

2. Auxiliary tools provide uniform external calls

3. Auxiliaries can be called repeatedly, but concurrent operations are not supported

Based on the above analysis:

  • Operator <manipulation code or specific manipulation behavior>is divided into five specific Operators: AOperator, BOperator, COperator, DOperator, EOperator, which operate on different application areas.
  • Manage Operator using Creative Mode
  • Use lock mechanism to limit concurrency
  • Outer layer encapsulates a single unit

IV. UML

V. Code Show

1. AuxiliaryToolSingleton provides calls to the outside world and uses a locking mechanism to control concurrency.

using System;
using System.Threading;
using DesignPatternDemo.Operator;
​
namespace DesignPatternDemo
{
    public class AuxiliaryToolSingleton
    {
        public static Semaphore OperatorSemaphore = new Semaphore(1, 1);
        private static readonly object OperatorLock = new object();
​
        public static AuxiliaryToolSingleton Instance = new AuxiliaryToolSingleton();
        private AuxiliaryToolSingleton()
        {
            RegistorOperator(OperatorFactory.Instance);
        }
​
        public void CallOperator(string operatorName, params string[] operatorParams)
        {
            //OperatorSemaphore.WaitOne();
            lock (OperatorLock)
            {
                Console.WriteLine($"Call method CallOperator :{operatorName} .Current Thread:{Thread.CurrentThread.ManagedThreadId}");
​
                BaseOperator concreteOperator = OperatorFactory.Instance.GetOperator(operatorName);
                concreteOperator.InitializationParameters(operatorParams);
                concreteOperator.Execute();
            }
​
            //OperatorSemaphore.Release();
        }
​
        public static void RegistorOperator(OperatorFactory factory)
        {
            factory.Register(nameof(AOperator), new AOperator());
            factory.Register(nameof(BOperator), new BOperator());
            factory.Register(nameof(COperator), new COperator());
            factory.Register(nameof(DOperator), new DOperator());
            factory.Register(nameof(EOperator), new EOperator());
        }
    }
}
 AuxiliaryToolSingleton

2. BaseOperator manipulates the base class, which contains some common, virtual, and parameter information.

using System;
using System.Threading;
​
namespace DesignPatternDemo.Operator
{
    public class BaseOperator
    {
        public string Name { get; set; }
        public string Description { get; set; }
​
        public void Execute()
        {
            //ToDo
            Thread.Sleep(new Random().Next(0, 5) * 1000);
            Console.WriteLine($"Execute concrete operator:{GetType().Name} .Current Thread:{Thread.CurrentThread.ManagedThreadId}");
            ConcreteOperate($"{GetType().Name}");
        }
        public void InitializationParameters(params string[] operatorParams)
        {
            //ToDo
​
            Console.WriteLine($"Initialization Parameters :{GetType().Name}");
        }
        private void ConcreteOperate(string mark)
        {
            // ToDo
            Console.WriteLine($"The concrete operation :{mark} was performed successfully .\r\n");
        }
        public virtual void ClickButtonByMark(string mark)
        {
            // ToDo
            ConcreteOperate(mark);
        }
​
        public virtual void ClickPopupMenuByMark(string mark)
        {
            // ToDo
            ConcreteOperate(mark);
        }
​
        public virtual void SelectDropdownBoxByIndex(int dropBoxIndex)
        {
            // ToDo
            ConcreteOperate($"{dropBoxIndex}");
        }
    }
}
 BaseOperator

3. AOperator specific manipulation class <e.g. click button>, implement ISpecialOperateA, inherit BaseOperator.

using System;
​
namespace DesignPatternDemo.Operator
{
    public class AOperator : BaseOperator, ISpecialOperateA
    {
        public void SetContent(string content)
        {
            //ToDo
            Console.WriteLine($"Filled the content:{content} successfully");
        }
        public string GetContent()
        {
            //ToDo
            return $"{new Random().Next()}{Guid.NewGuid()}";
        }
    }
}
​
namespace DesignPatternDemo.Operator
{
    public interface ISpecialOperateA
    {
        void SetContent(string content);
        string GetContent();
    }
}
 AOperator

4. BOperator, COperator, DOperator specific manipulation classes.

namespace DesignPatternDemo.Operator
{
    public class BOperator : BaseOperator
    {
    }
}
​
namespace DesignPatternDemo.Operator
{
    public class COperator : BaseOperator
    {
    }
}
​
namespace DesignPatternDemo.Operator
{
    public class DOperator : BaseOperator
    {
    }
}
 Concrete Operator

5. EOperator specific manipulation class <such as manipulation tree control>, implement ISpecialOperateE, inherit BaseOperator.

using System;
​
namespace DesignPatternDemo.Operator
{
    public class EOperator : BaseOperator, ISpecialOperateE
    {
        public void ClickTreeviewByMark(string mark)
        {
            //ToDo
            Console.WriteLine($"{mark}: execution succeed");
        }
    }
}
​
namespace DesignPatternDemo.Operator
{
    public interface ISpecialOperateE
    {
        void ClickTreeviewByMark(string mark);
    }
}
 EOperator

6. Factory factory class base class, which can register, delete, and get specific classes based on key.Creative mode.

using System.Collections.Generic;
​
namespace DesignPatternDemo
{
    public class Factory<TF, TV> where TF : new()
    {
        protected Factory()
        {
            KeyValues = new Dictionary<string, TV>();
        }
​
        public static TF Instance { get; set; } = new TF();
​
        private Dictionary<string, TV> KeyValues { get; }
​
        public TV GetItem(string key)
{
            KeyValues.TryGetValue(key, out TV find);
​
            return find;
        }
        public void Register(string key, TV t)
{
            UnRegister(key);
            KeyValues.Add(key, t);
        }
​
        public void UnRegister(string key)
{
            if (KeyValues.ContainsKey(key)) KeyValues.Remove(key);
        }
    }
}
 Factory

7. OperatorFactory specific factory, inherits Factory.

using DesignPatternDemo.Operator;
​
namespace DesignPatternDemo
{
    public class OperatorFactory : Factory<OperatorFactory, BaseOperator>
    {
        public BaseOperator GetOperator(string operatorName)
{
            return GetItem(operatorName);
        }
    }
}
 OperatorFactory

8. Program console program that invokes simulation using parallel libraries and Task multithreads, respectively.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using DesignPatternDemo.Operator;
​
namespace DesignPatternDemo
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
​
            List<string> concreteOperators = GetConcreteOperators();
​
            Parallel.ForEach(concreteOperators, current => { CallOperator(current); });
​
            foreach (string operatorName in concreteOperators)
            {
                Task concreteTask = new Task(() => { CallOperator(operatorName); });
                concreteTask.Start();
            }
​
            Console.ReadKey();
        }
        private static List<string> GetConcreteOperators()
        {
            List<string> concreteOperators = new List<string>
            {
                nameof(AOperator),
                nameof(BOperator),
                nameof(COperator),
                nameof(DOperator),
                nameof(EOperator)
            };
            return concreteOperators;
        }
​
        private static void CallOperator(string operatorName, params string[] operatorParams)
        {
            AuxiliaryToolSingleton auxiliaryTool = AuxiliaryToolSingleton.Instance;
            auxiliaryTool.CallOperator(operatorName, operatorParams);
        }
    }
}
 Program

6. Description and Summary

  • The purpose of this article is to illustrate a review of the use of some patterns, the business of the original project, the code structure, and the implementation language that have been changed or simplified.
  • The UML description can be implemented in any OO language.
  • You can use Table Driven, Strategy Patterns to avoid many conditional judgments.
  • The pattern suite corresponds to the scene.
  • Demo code environment: vs2017.Net Core2.2

Text source network, for learning purposes only. If there is infringement, contact for deletion.

I've put together good technical articles and a summary of my experience in my public number, the Java Circle.

To facilitate your learning, I have compiled a set of learning materials, including Java virtual machines, spring framework, Java threads, data structures, design patterns, and so on, which are free for those who love Java!More learning and communication groups, more communication problems can make faster progress ~

Tags: Programming Java network Spring

Posted on Sat, 28 Mar 2020 00:04:40 -0700 by Dave100