Object-Oriented Design (OOD) helps us develop high-performance, extensible and reusable programs. One of the important ideas of OOD is that it relies on the inversion principle (DIP).
Dependency Inversion Principle (DIP): A Principle of Software Architecture Design (Abstract Concept)
Inversion of Control (IoC): A way to reverse flows, dependencies, and interfaces (the specific implementation of DIP)
Dependency Injection (DI): An implementation of IoC for inverting dependencies (the specific implementation of IoC)
IoC container: Dependency injection framework for mapping dependencies, managing object creation and lifecycle (DI framework), and
Unity: Microsoft's IOC framework
TDD: Test-driven development is a core practice and technology in agile development and a design methodology.
The contents above are all copied (English is not good, put here for reference), the relevant content read some, not conscious.
Have written a hotel room card reading and writing procedures, different hotel door locks are different, the same hotel may also change the door locks, procedures:
1. Obtaining the Lock Type of the Current Hotel by Api
2. Download the dll corresponding to the door lock if necessary
3. Realize the function of reading and writing
I. Defining interfaces
Create a new class library (Lock.Interface) with the following code:
namespace Lock { public interface ILock { /// <summary> ///Door lock initialization /// </summary> /// <param name= "password">initialization password </param> /// <returns></returns> bool Init(int password); } }
Is it IoC? (I'm not sure)
Unit testing
Create a new unit test project (Lock.Tests), code as follows:
1. Unit Test of Door Lock A
/// <summary> /// Door lock A test /// </summary> [TestClass()] public class LockATests { /// <summary> /// Initialization, password Positive odd numbers /// </summary> [TestMethod()] public void InitTest() { ILock l = new LockA(); var ret = l.Init(1); Assert.AreEqual(ret, true); ret = l.Init(2); Assert.AreEqual(ret, false); ret = l.Init(-1); Assert.AreEqual(ret, false); } }
2. Lock B Unit Testing
/// <summary> ///Door Lock B Test /// </summary> [TestClass()] public class LockBTests { /// <summary> /// Initialization test, password is positive even number /// </summary> [TestMethod()] public void InitTest() { ILock l = new LockB(); var ret = l.Init(1); Assert.AreEqual(ret, false); ret = l.Init(2); Assert.AreEqual(ret, true); ret = l.Init(-1); Assert.AreEqual(ret, false); }
Obviously compilation can't pass (not compilation is also a test)
Definition Classes
1. Create a class library of lock A (Lock.LockA), code as follows:
/// <summary> //Door lock A /// </summary> public class LockA : ILock { /// <summary> //Initialization /// </summary> ///<param name="password">The correct password is a positive odd number </param> /// <returns></returns> public bool Init(int password) { return password > 0 && (password % 2) == 1; } }
2. Create Lock Class B Library (Lock.LockB), code as follows:
/// <summary> //Door lock B /// </summary> public class LockB : ILock { /// <summary> //Initialization /// </summary> /// <param name="password">The correct password is a positive even number </param> /// <returns></returns> public bool Init(int password) { return password > 0 && (password % 2) == 0; } }
After successful compilation, return to the test project, add references, compile and run the test:
Does it count as TDD?
IV. MAIN PROCEDURE
1. Add console project
2. Add Unity (5.8.6) package
3. Modify App.Config to:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Unity.Configuration, Version=5.2.1.0, Culture=neutral, PublicKeyToken=6d32ff45e0ccc69f" />
<!--Some of the previous content was duplicated on the Internet with errors, and later checked UnityConfigurationSection Definition, duplicate the corresponding assembly
type="Namespace.Class name,Assembly"
-->
</configSections>
<unity>
<containers>
<container name="LockA">
<register type="Lock.ILock,Lock.Interface" mapTo="Lock.LockA,Lock.LockA" ></register>
</container>
<container name="LockB">
<register type="Lock.ILock,Lock.Interface" mapTo="Lock.LockB,Lock.LockB"></register>
</container>
</containers>
</unity>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
</configuration>
4. Reference Interface
5.Main's method is as follows:
static void Main(string[] args) { var container = new UnityContainer(); UnityConfigurationSection config = (UnityConfigurationSection)ConfigurationManager.GetSection(UnityConfigurationSection.SectionName); config.Configure(container, "LockA");
ILock l = container.Resolve<ILock>(); Console.WriteLine(l.Init(2)); Console.WriteLine(l.Init(1)); Console.WriteLine(l.Init(-1));
Console.ReadKey(); }
6. Copy the dll of Door Lock A to the running directory
7. Running results such as False, True and False are the results of door lock A.
8. Change "LockA" to "LockB" and copy the dll of lock B to the running directory. The running results are True, False and False, which are the results of lock B.
Count DI? We all use Unity.
So far, we have basically achieved the desired functions. In the future, it is no problem for new hotels to add lock C and lock D. Only the problem of changing old hotels to lock E has not been solved (it is estimated that it can be achieved by dynamically modifying config files, and we do not know if there is a better way).