一、接口设计的好处
三大好处:解耦、可复用、可扩展。
二、简单工厂模式
【三要素】能创建具体产品的工厂、抽象产品(接口)、具体产品
【基本用法】字符串=>创建对象=>调用其方法
// 产品接口
public interface IProduct
{
void Operation();
}
// 具体产品 A
public class ProductA : IProduct
{
public void Operation() => Console.WriteLine("ProductA Operation");//表达式主体方法写法,就是写括号
}
// 具体产品 B
public class ProductB : IProduct
{
public void Operation() => Console.WriteLine("ProductB Operation");
}
// 工厂类
public class ProductFactory
{
public static IProduct CreateProduct(string type)
{
return type switch //简化版switch 语句,和if,else一个意思
{
"A" => new ProductA(),
"B" => new ProductB(),
_ => throw new ArgumentException("Invalid product type")
};
}
}
// 主程序
class Program
{
static void Main()
{
string input = "A";
IProduct product = ProductFactory.CreateProduct(input);
product.Operation(); // Output: ProductA Operation
}
}
【思考】以下方法也可以调用接口,为什么非要用工厂模式呢?
string input = "A";
if (input=="A")
{
var product = new ProductA();
product.Operation();
}
请看图,我告诉你为什么要用工厂模式:
1.假如后续我加了产品CDEFGHI...,我仅需要添加代码到工厂类和具体实现 (底层代码),而无需修改高层代码,做到了开闭原则。
2.用工厂模式实现了解耦,避免了高层代码和底层代码紧密的联系,使得高层代码无需关注具体的实现过程,做到了依赖于抽象,不依赖于具体(依赖倒置原则)。
三、抽象工厂模式
【思考】简单工厂和抽象工厂的区别
简单工厂模式:适用于单一类型的对象创建。
抽象工厂模式:适合创建一系列相关的产品族,每个产品族包含多个不同类型的产品。它提供了更高的灵活性和扩展性。
【代码实现】
// 抽象产品 A
public interface IProductA
{
void OperationA();
}
// 抽象产品 B
public interface IProductB
{
void OperationB();
}
// 具体产品 A1
public class ProductA1 : IProductA
{
public void OperationA() => Console.WriteLine("ProductA1 OperationA");
}
// 具体产品 B1
public class ProductB1 : IProductB
{
public void OperationB() => Console.WriteLine("ProductB1 OperationB");
}
// 具体产品 A2
public class ProductA2 : IProductA
{
public void OperationA() => Console.WriteLine("ProductA2 OperationA");
}
// 具体产品 B2
public class ProductB2 : IProductB
{
public void OperationB() => Console.WriteLine("ProductB2 OperationB");
}
// 抽象工厂
public interface IFactory
{
IProductA CreateProductA();
IProductB CreateProductB();
}
// 具体工厂 1
public class Factory1 : IFactory
{
public IProductA CreateProductA() => new ProductA1();
public IProductB CreateProductB() => new ProductB1();
}
// 具体工厂 2
public class Factory2 : IFactory
{
public IProductA CreateProductA() => new ProductA2();
public IProductB CreateProductB() => new ProductB2();
}
// 主程序
class Program
{
static void Main()
{
IFactory factory = new Factory1();
IProductA productA = factory.CreateProductA();
IProductB productB = factory.CreateProductB();
productA.OperationA(); // Output: ProductA1 OperationA
productB.OperationB(); // Output: ProductB1 OperationB
}
}
四、策略模式
【三要素】环境类(用户这个对象)、策略接口、实现接口
【基本用法】对象不同=>选择的策略不同=>实现策略不同
【demo】
using System;
public interface IDiscountStrategy
{
double ApplyDiscount(double price);
}
public class GoldMemberDiscount : IDiscountStrategy
{
public double ApplyDiscount(double price)
{
return price * 0.95; // 5% off
}
}
public class RegularMemberDiscount : IDiscountStrategy
{
public double ApplyDiscount(double price)
{
return price; // No discount
}
}
public class Ticket
{
private readonly IDiscountStrategy _discountStrategy;
public Ticket(IDiscountStrategy discountStrategy)
{
_discountStrategy = discountStrategy;
}
public double GetPrice(double originalPrice)
{
return _discountStrategy.ApplyDiscount(originalPrice);
}
}
public class Program
{
public static void Main()
{
double originalPrice = 100.0;
//策略模式:分为两步
Ticket goldMemberTicket = new Ticket(new GoldMemberDiscount());//1.选择策略
Console.WriteLine("Gold Member Price: " + goldMemberTicket.GetPrice(originalPrice));//2.执行策略
Ticket regularMemberTicket = new Ticket(new RegularMemberDiscount());
Console.WriteLine("Regular Member Price: " + regularMemberTicket.GetPrice(originalPrice));
}
}
【思考】为什么要选取策略模式?其实分析思路和工厂模式差不多:
1.符合开闭原则,新加策略可以直接加实现策略即可,而工厂模式还需要修改工厂类和实现产品。
2.消除if-else语句,将算法逻辑封装在了具体策略中,高层代码(主程序)只需要调用GetPrice 方法即可(用户的身份信息可由查表获得,无需if判断)。
3.复用性强,一套算法可以多次使用。