Skip to content

Commit fe3d56b

Browse files
committed
Added Proxy Pattern
1 parent 6b8bbb0 commit fe3d56b

File tree

9 files changed

+155
-21
lines changed

9 files changed

+155
-21
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System;
2+
3+
namespace SoftwarePatterns.Core.Proxy
4+
{
5+
public class Order
6+
{
7+
public int Id { get; set; }
8+
public string Name { get; set; }
9+
public DateTime OrderDate { get; set; }
10+
public int[] OrderDetails { get; set; }
11+
public int CustomerId { get; set; }
12+
}
13+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System;
2+
using System.Runtime.Caching;
3+
4+
namespace SoftwarePatterns.Core.Proxy
5+
{
6+
public class OrderCacheRepository : OrderRepository
7+
{
8+
public override Order GetById(int id)
9+
{
10+
var cacheKey = CreateCacheKey<Order>(id);
11+
var entity = MemoryCache.Default[cacheKey] as Order;
12+
13+
if (entity == null)
14+
{
15+
entity = base.GetById(id);
16+
var cacheItem = new CacheItem(cacheKey, entity);
17+
var policy = new CacheItemPolicy();
18+
MemoryCache.Default.Add(cacheItem, policy);
19+
}
20+
return entity;
21+
}
22+
23+
private static string CreateCacheKey<T>(params object[] parms)
24+
{
25+
var paramKey = string.Join("-", parms.ToString());
26+
27+
if(string.IsNullOrEmpty(paramKey) || string.IsNullOrWhiteSpace(paramKey)) throw new ArgumentException("Parameter provided could not be used to generate cache key");
28+
29+
return string.Format("{0}-{1}", typeof (T).Name.ToLowerInvariant(), paramKey);
30+
}
31+
}
32+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System;
2+
using System.Linq;
3+
4+
namespace SoftwarePatterns.Core.Proxy
5+
{
6+
public class OrderRepository : Repository<Order>
7+
{
8+
9+
public override Order GetById(int id)
10+
{
11+
OrderFetched++;
12+
Console.WriteLine("Going to database to get order");
13+
return new Order
14+
{
15+
Id = id,
16+
CustomerId = 1,
17+
OrderDate = DateTime.Now,
18+
OrderDetails = new[] {1, 2, 34}
19+
};
20+
}
21+
22+
public int OrderFetched { get; set; }
23+
}
24+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Define:
2+
A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection,
3+
a large object in memory, a file, or some other resource that is expensive or impossible to duplicate.
4+
5+
Usage:
6+
A remote proxy acts as a local representative of a remote object and abstracts away the details of the communication with the remote object.
7+
A virtual proxy creates expensive objects on demand.
8+
A protection proxy can be used to control access to the object, based on authorisation rules.
9+
10+
Examples:
11+
We have already seen examples of the proxy object in the lazy loading pattern where objects or properties are loaded only when requested by the client
12+
13+
Consequences
14+
Proxy objects must be kept up to date with the real object either manually or via code generation (this is common in ORM or remote proxy in WCF)
15+
Client code may make incorrect assumptions about the behaviour of real objects
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace SoftwarePatterns.Core.Proxy
2+
{
3+
public abstract class Repository<T>
4+
{
5+
public abstract T GetById(int id);
6+
}
7+
}

src/SoftwarePatterns.Core/SoftwarePatterns.Core.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
<Reference Include="System" />
3434
<Reference Include="System.Core" />
3535
<Reference Include="System.Drawing" />
36+
<Reference Include="System.Runtime.Caching" />
3637
<Reference Include="System.Xml.Linq" />
3738
<Reference Include="System.Data.DataSetExtensions" />
3839
<Reference Include="Microsoft.CSharp" />
@@ -154,6 +155,10 @@
154155
<Compile Include="Observer\PubSub\MicrosftStockObserver.cs" />
155156
<Compile Include="Observer\PubSub\SimpleStockTicker.cs" />
156157
<Compile Include="Properties\AssemblyInfo.cs" />
158+
<Compile Include="Proxy\Order.cs" />
159+
<Compile Include="Proxy\OrderCacheRepository.cs" />
160+
<Compile Include="Proxy\OrderRepository.cs" />
161+
<Compile Include="Proxy\Repository.cs" />
157162
</ItemGroup>
158163
<ItemGroup>
159164
<Content Include="Adapter\ReadMe.txt" />
@@ -176,6 +181,7 @@
176181
<Content Include="NullObject\ReadMe.txt" />
177182
<Content Include="Observer\ReadMe.txt" />
178183
<Content Include="PatternList.txt" />
184+
<Content Include="Proxy\ReadMe.txt" />
179185
</ItemGroup>
180186
<ItemGroup />
181187
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using SoftwarePatterns.Core.Proxy;
2+
using Xunit;
3+
4+
namespace SoftwarePatterns.Tests.Proxy
5+
{
6+
public class OrderRepositoryTests
7+
{
8+
public class GetByIdMethod
9+
{
10+
[Fact]
11+
public void ShouldOnlyFetchOnce()
12+
{
13+
var repository = new OrderCacheRepository();
14+
var order1 = repository.GetById(1);
15+
var order2 = repository.GetById(1);
16+
var order3 = repository.GetById(1);
17+
18+
Assert.Equal(1, repository.OrderFetched);
19+
}
20+
}
21+
}
22+
}

src/SoftwarePatterns.Tests/SoftwarePatterns.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
<Compile Include="NullObject\AutoRepositoryTests.cs" />
8585
<Compile Include="Observer\ObserverTests.cs" />
8686
<Compile Include="Properties\AssemblyInfo.cs" />
87+
<Compile Include="Proxy\OrderRepositoryTests.cs" />
8788
</ItemGroup>
8889
<ItemGroup>
8990
<None Include="packages.config" />

src/SoftwarePatterns/Program.cs

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
using SoftwarePatterns.Core.Observer.EventDelegate;
2323
using SoftwarePatterns.Core.Observer.IObserver;
2424
using SoftwarePatterns.Core.Observer.PubSub;
25+
using SoftwarePatterns.Core.Proxy;
2526

2627
namespace SoftwarePatterns
2728
{
@@ -350,37 +351,50 @@ class Program
350351

351352
#region Observer
352353

353-
public static void Main()
354-
{
355-
//Simple classic pub sub model
356-
//var ticker = new SimpleStockTicker();
354+
//public static void Main()
355+
//{
356+
// //Simple classic pub sub model
357+
// //var ticker = new SimpleStockTicker();
357358

358-
//var google = new GoogleStockObserver(ticker);
359-
//var msft = new MicrosftStockObserver(ticker);
359+
// //var google = new GoogleStockObserver(ticker);
360+
// //var msft = new MicrosftStockObserver(ticker);
360361

361-
//ticker.RunTicker();
362+
// //ticker.RunTicker();
362363

363-
//Event and delegate based approach
364+
// //Event and delegate based approach
364365

365-
//var ticker = new EventStockTicker();
366+
// //var ticker = new EventStockTicker();
366367

367-
//var google = new GoogleEventStockObserver(ticker);
368-
//var msft = new MicrosoftEventStockObserver(ticker);
368+
// //var google = new GoogleEventStockObserver(ticker);
369+
// //var msft = new MicrosoftEventStockObserver(ticker);
369370

370-
//ticker.RunTicker();
371+
// //ticker.RunTicker();
371372

372-
//using IObserver<T>
373+
// //using IObserver<T>
373374

374-
var ticker = new ObservableStockTicker();
375+
// var ticker = new ObservableStockTicker();
375376

376-
var google = new GoogleObserver();
377-
var msft = new MicrosoftObserver();
377+
// var google = new GoogleObserver();
378+
// var msft = new MicrosoftObserver();
378379

379-
using (ticker.Subscribe(google))
380-
using (ticker.Subscribe(msft))
381-
{
382-
ticker.RunTicker();
383-
}
380+
// using (ticker.Subscribe(google))
381+
// using (ticker.Subscribe(msft))
382+
// {
383+
// ticker.RunTicker();
384+
// }
385+
386+
// Console.ReadLine();
387+
//}
388+
389+
#endregion
390+
391+
#region Proxy
392+
393+
public static void Main()
394+
{
395+
var order1 = new OrderCacheRepository().GetById(1);
396+
var order2 = new OrderCacheRepository().GetById(1);
397+
var order3 = new OrderCacheRepository().GetById(1);
384398

385399
Console.ReadLine();
386400
}

0 commit comments

Comments
 (0)